From 4fce380c13b340661b3c7100ebd13cb87e6bac01 Mon Sep 17 00:00:00 2001 From: Virt <41426325+VirtCode@users.noreply.github.com> Date: Sat, 22 Jun 2024 15:46:00 +0200 Subject: [PATCH] fix: recalulate on mouse move, not render --- src/cursor.cpp | 24 ++++++++++++++++++------ src/cursor.hpp | 7 +++++-- src/globals.hpp | 1 + src/main.cpp | 28 +++++++++++++++++++++++----- 4 files changed, 47 insertions(+), 13 deletions(-) diff --git a/src/cursor.cpp b/src/cursor.cpp index f3874e3..313e08a 100644 --- a/src/cursor.cpp +++ b/src/cursor.cpp @@ -51,7 +51,7 @@ void CDynamicCursors::renderSoftware(CPointerManager* pointers, SP pMo box.scale(pMonitor->scale); // we rotate the cursor by our calculated amount - box.rot = this->calculate(&pointers->pointerPos); + box.rot = this->angle; // now pass the hotspot to rotate around renderCursorTextureInternalWithDamage(texture, &box, &damage, 1.F, pointers->currentCursorImage.hotspot); @@ -151,7 +151,7 @@ wlr_buffer* CDynamicCursors::renderHardware(CPointerManager* pointers, SPcurrentCursorImage.size / pointers->currentCursorImage.scale * state->monitor->scale}.round()}; - xbox.rot = this->calculate(&pointers->pointerPos); + xbox.rot = this->angle; // use our custom draw function renderCursorTextureInternalWithDamage(texture, &xbox, &damage, 1.F, pointers->currentCursorImage.hotspot); @@ -198,6 +198,8 @@ void CDynamicCursors::onCursorMoved(CPointerManager* pointers) { if (!pointers->hasCursor()) return; + bool changed = calculate(&pointers->pointerPos); + for (auto& m : g_pCompositor->m_vMonitors) { auto state = pointers->stateFor(m); @@ -206,12 +208,16 @@ void CDynamicCursors::onCursorMoved(CPointerManager* pointers) { if (state->hardwareFailed || !state->entered) continue; - // we set a new hardware cursor on every move - pointers->attemptHardwareCursor(state); + const auto CURSORPOS = pointers->getCursorPosForMonitor(m); + m->output->impl->move_cursor(m->output, CURSORPOS.x, CURSORPOS.y); + + // we set a new hardware cursor if the angle has changed significantly + if (changed) + pointers->attemptHardwareCursor(state); } } -double CDynamicCursors::calculate(Vector2D* pos) { +bool CDynamicCursors::calculate(Vector2D* pos) { static auto* const* PLENGTH = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, CONFIG_LENGTH)->getDataStaticPtr(); // translate to origin @@ -236,5 +242,11 @@ double CDynamicCursors::calculate(Vector2D* pos) { end.x += pos->x; end.y += pos->y; - return angle; + // we only consider the angle changed if it is larger than 1 degree + if (abs(this->angle - angle) > (PI / 180)) { + this->angle = angle; + return true; + } + + return false; } diff --git a/src/cursor.hpp b/src/cursor.hpp index 39eec13..460a454 100644 --- a/src/cursor.hpp +++ b/src/cursor.hpp @@ -21,8 +21,11 @@ class CDynamicCursors { bool setHardware(CPointerManager* pointers, SP state, wlr_buffer* buf); private: - // calculates the current angle of the cursor - double calculate(Vector2D* pos); + // current angle of the cursor in radiants + double angle; + + // calculates the current angle of the cursor, returns whether the angle has changed + bool calculate(Vector2D* pos); // this is the end of the virtual stick Vector2D end; }; diff --git a/src/globals.hpp b/src/globals.hpp index 78066ae..014184c 100644 --- a/src/globals.hpp +++ b/src/globals.hpp @@ -2,6 +2,7 @@ #include +#define CONFIG_ENABLED "plugin:dynamic-cursors:enabled" #define CONFIG_LENGTH "plugin:dynamic-cursors:length" #define CONFIG_HW_DEBUG "plugin:dynamic-cursors:hw_debug" diff --git a/src/main.cpp b/src/main.cpp index 76ea88d..8182cf1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -11,31 +11,46 @@ typedef void (*origRenderSofwareCursorsFor)(void*, SP, timespec*, CRegion&, std::optional); inline CFunctionHook* g_pRenderSoftwareCursorsForHook = nullptr; void hkRenderSoftwareCursorsFor(void* thisptr, SP pMonitor, timespec* now, CRegion& damage, std::optional overridePos) { - g_pDynamicCursors->renderSoftware((CPointerManager*) thisptr, pMonitor, now, damage, overridePos); + static auto* const* PENABLED = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, CONFIG_ENABLED)->getDataStaticPtr(); + + if (**PENABLED) g_pDynamicCursors->renderSoftware((CPointerManager*) thisptr, pMonitor, now, damage, overridePos); + else (*(origRenderSofwareCursorsFor)g_pRenderSoftwareCursorsForHook->m_pOriginal)(thisptr, pMonitor, now, damage, overridePos); } typedef void (*origDamageIfSoftware)(void*); inline CFunctionHook* g_pDamageIfSoftwareHook = nullptr; void hkDamageIfSoftware(void* thisptr) { - g_pDynamicCursors->damageSoftware((CPointerManager*) thisptr); + static auto* const* PENABLED = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, CONFIG_ENABLED)->getDataStaticPtr(); + + if (**PENABLED) g_pDynamicCursors->damageSoftware((CPointerManager*) thisptr); + else (*(origDamageIfSoftware)g_pDamageIfSoftwareHook->m_pOriginal)(thisptr); } typedef wlr_buffer* (*origRenderHWCursorBuffer)(void*, SP, SP); inline CFunctionHook* g_pRenderHWCursorBufferHook = nullptr; wlr_buffer* hkRenderHWCursorBuffer(void* thisptr, SP state, SP texture) { - return g_pDynamicCursors->renderHardware((CPointerManager*) thisptr, state, texture); + static auto* const* PENABLED = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, CONFIG_ENABLED)->getDataStaticPtr(); + + if (**PENABLED) return g_pDynamicCursors->renderHardware((CPointerManager*) thisptr, state, texture); + else return (*(origRenderHWCursorBuffer)g_pRenderHWCursorBufferHook->m_pOriginal)(thisptr, state, texture); } typedef bool (*origSetHWCursorBuffer)(void*, SP, wlr_buffer*); inline CFunctionHook* g_pSetHWCursorBufferHook = nullptr; bool hkSetHWCursorBuffer(void* thisptr, SP state, wlr_buffer* buffer) { - return g_pDynamicCursors->setHardware((CPointerManager*) thisptr, state, buffer); + static auto* const* PENABLED = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, CONFIG_ENABLED)->getDataStaticPtr(); + + if (**PENABLED) return g_pDynamicCursors->setHardware((CPointerManager*) thisptr, state, buffer); + else return (*(origSetHWCursorBuffer)g_pSetHWCursorBufferHook->m_pOriginal)(thisptr, state, buffer); } typedef void (*origOnCursorMoved)(void*); inline CFunctionHook* g_pOnCursorMovedHook = nullptr; void hkOnCursorMoved(void* thisptr) { - return g_pDynamicCursors->onCursorMoved((CPointerManager*) thisptr); + static auto* const* PENABLED = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, CONFIG_ENABLED)->getDataStaticPtr(); + + if (**PENABLED) return g_pDynamicCursors->onCursorMoved((CPointerManager*) thisptr); + else return (*(origOnCursorMoved)g_pOnCursorMovedHook->m_pOriginal)(thisptr); } APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) { @@ -71,9 +86,12 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) { g_pOnCursorMovedHook = HyprlandAPI::createFunctionHook(PHANDLE, ON_CURSOR_MOVED_METHODS[0].address, (void*) &hkOnCursorMoved); g_pOnCursorMovedHook->hook(); + HyprlandAPI::addConfigValue(PHANDLE, CONFIG_ENABLED, Hyprlang::INT{1}); HyprlandAPI::addConfigValue(PHANDLE, CONFIG_LENGTH, Hyprlang::INT{20}); HyprlandAPI::addConfigValue(PHANDLE, CONFIG_HW_DEBUG, Hyprlang::INT{0}); + HyprlandAPI::reloadConfig(); + return {"dynamic-cursors", "The most stupid cursor plugin.", "Virt", "1.1"}; }