mirror of
https://github.com/virtcode/hypr-dynamic-cursors
synced 2025-09-19 16:13:21 +02:00
fix: recalulate on mouse move, not render
This commit is contained in:
parent
581a094b7b
commit
4fce380c13
4 changed files with 47 additions and 13 deletions
|
@ -51,7 +51,7 @@ void CDynamicCursors::renderSoftware(CPointerManager* pointers, SP<CMonitor> pMo
|
||||||
box.scale(pMonitor->scale);
|
box.scale(pMonitor->scale);
|
||||||
|
|
||||||
// we rotate the cursor by our calculated amount
|
// 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
|
// now pass the hotspot to rotate around
|
||||||
renderCursorTextureInternalWithDamage(texture, &box, &damage, 1.F, pointers->currentCursorImage.hotspot);
|
renderCursorTextureInternalWithDamage(texture, &box, &damage, 1.F, pointers->currentCursorImage.hotspot);
|
||||||
|
@ -151,7 +151,7 @@ wlr_buffer* CDynamicCursors::renderHardware(CPointerManager* pointers, SP<CPoint
|
||||||
|
|
||||||
// the box should start in the middle portion, rotate by our calculated amount
|
// the box should start in the middle portion, rotate by our calculated amount
|
||||||
CBox xbox = {size, Vector2D{pointers->currentCursorImage.size / pointers->currentCursorImage.scale * state->monitor->scale}.round()};
|
CBox xbox = {size, Vector2D{pointers->currentCursorImage.size / pointers->currentCursorImage.scale * state->monitor->scale}.round()};
|
||||||
xbox.rot = this->calculate(&pointers->pointerPos);
|
xbox.rot = this->angle;
|
||||||
|
|
||||||
// use our custom draw function
|
// use our custom draw function
|
||||||
renderCursorTextureInternalWithDamage(texture, &xbox, &damage, 1.F, pointers->currentCursorImage.hotspot);
|
renderCursorTextureInternalWithDamage(texture, &xbox, &damage, 1.F, pointers->currentCursorImage.hotspot);
|
||||||
|
@ -198,6 +198,8 @@ void CDynamicCursors::onCursorMoved(CPointerManager* pointers) {
|
||||||
if (!pointers->hasCursor())
|
if (!pointers->hasCursor())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
bool changed = calculate(&pointers->pointerPos);
|
||||||
|
|
||||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||||
auto state = pointers->stateFor(m);
|
auto state = pointers->stateFor(m);
|
||||||
|
|
||||||
|
@ -206,12 +208,16 @@ void CDynamicCursors::onCursorMoved(CPointerManager* pointers) {
|
||||||
if (state->hardwareFailed || !state->entered)
|
if (state->hardwareFailed || !state->entered)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// we set a new hardware cursor on every move
|
const auto CURSORPOS = pointers->getCursorPosForMonitor(m);
|
||||||
pointers->attemptHardwareCursor(state);
|
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();
|
static auto* const* PLENGTH = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, CONFIG_LENGTH)->getDataStaticPtr();
|
||||||
|
|
||||||
// translate to origin
|
// translate to origin
|
||||||
|
@ -236,5 +242,11 @@ double CDynamicCursors::calculate(Vector2D* pos) {
|
||||||
end.x += pos->x;
|
end.x += pos->x;
|
||||||
end.y += pos->y;
|
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,8 +21,11 @@ class CDynamicCursors {
|
||||||
bool setHardware(CPointerManager* pointers, SP<CPointerManager::SMonitorPointerState> state, wlr_buffer* buf);
|
bool setHardware(CPointerManager* pointers, SP<CPointerManager::SMonitorPointerState> state, wlr_buffer* buf);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// calculates the current angle of the cursor
|
// current angle of the cursor in radiants
|
||||||
double calculate(Vector2D* pos);
|
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
|
// this is the end of the virtual stick
|
||||||
Vector2D end;
|
Vector2D end;
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include <hyprland/src/plugins/PluginAPI.hpp>
|
#include <hyprland/src/plugins/PluginAPI.hpp>
|
||||||
|
|
||||||
|
#define CONFIG_ENABLED "plugin:dynamic-cursors:enabled"
|
||||||
#define CONFIG_LENGTH "plugin:dynamic-cursors:length"
|
#define CONFIG_LENGTH "plugin:dynamic-cursors:length"
|
||||||
#define CONFIG_HW_DEBUG "plugin:dynamic-cursors:hw_debug"
|
#define CONFIG_HW_DEBUG "plugin:dynamic-cursors:hw_debug"
|
||||||
|
|
||||||
|
|
28
src/main.cpp
28
src/main.cpp
|
@ -11,31 +11,46 @@
|
||||||
typedef void (*origRenderSofwareCursorsFor)(void*, SP<CMonitor>, timespec*, CRegion&, std::optional<Vector2D>);
|
typedef void (*origRenderSofwareCursorsFor)(void*, SP<CMonitor>, timespec*, CRegion&, std::optional<Vector2D>);
|
||||||
inline CFunctionHook* g_pRenderSoftwareCursorsForHook = nullptr;
|
inline CFunctionHook* g_pRenderSoftwareCursorsForHook = nullptr;
|
||||||
void hkRenderSoftwareCursorsFor(void* thisptr, SP<CMonitor> pMonitor, timespec* now, CRegion& damage, std::optional<Vector2D> overridePos) {
|
void hkRenderSoftwareCursorsFor(void* thisptr, SP<CMonitor> pMonitor, timespec* now, CRegion& damage, std::optional<Vector2D> 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*);
|
typedef void (*origDamageIfSoftware)(void*);
|
||||||
inline CFunctionHook* g_pDamageIfSoftwareHook = nullptr;
|
inline CFunctionHook* g_pDamageIfSoftwareHook = nullptr;
|
||||||
void hkDamageIfSoftware(void* thisptr) {
|
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<CPointerManager::SMonitorPointerState>, SP<CTexture>);
|
typedef wlr_buffer* (*origRenderHWCursorBuffer)(void*, SP<CPointerManager::SMonitorPointerState>, SP<CTexture>);
|
||||||
inline CFunctionHook* g_pRenderHWCursorBufferHook = nullptr;
|
inline CFunctionHook* g_pRenderHWCursorBufferHook = nullptr;
|
||||||
wlr_buffer* hkRenderHWCursorBuffer(void* thisptr, SP<CPointerManager::SMonitorPointerState> state, SP<CTexture> texture) {
|
wlr_buffer* hkRenderHWCursorBuffer(void* thisptr, SP<CPointerManager::SMonitorPointerState> state, SP<CTexture> 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<CPointerManager::SMonitorPointerState>, wlr_buffer*);
|
typedef bool (*origSetHWCursorBuffer)(void*, SP<CPointerManager::SMonitorPointerState>, wlr_buffer*);
|
||||||
inline CFunctionHook* g_pSetHWCursorBufferHook = nullptr;
|
inline CFunctionHook* g_pSetHWCursorBufferHook = nullptr;
|
||||||
bool hkSetHWCursorBuffer(void* thisptr, SP<CPointerManager::SMonitorPointerState> state, wlr_buffer* buffer) {
|
bool hkSetHWCursorBuffer(void* thisptr, SP<CPointerManager::SMonitorPointerState> 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*);
|
typedef void (*origOnCursorMoved)(void*);
|
||||||
inline CFunctionHook* g_pOnCursorMovedHook = nullptr;
|
inline CFunctionHook* g_pOnCursorMovedHook = nullptr;
|
||||||
void hkOnCursorMoved(void* thisptr) {
|
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) {
|
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 = HyprlandAPI::createFunctionHook(PHANDLE, ON_CURSOR_MOVED_METHODS[0].address, (void*) &hkOnCursorMoved);
|
||||||
g_pOnCursorMovedHook->hook();
|
g_pOnCursorMovedHook->hook();
|
||||||
|
|
||||||
|
HyprlandAPI::addConfigValue(PHANDLE, CONFIG_ENABLED, Hyprlang::INT{1});
|
||||||
HyprlandAPI::addConfigValue(PHANDLE, CONFIG_LENGTH, Hyprlang::INT{20});
|
HyprlandAPI::addConfigValue(PHANDLE, CONFIG_LENGTH, Hyprlang::INT{20});
|
||||||
HyprlandAPI::addConfigValue(PHANDLE, CONFIG_HW_DEBUG, Hyprlang::INT{0});
|
HyprlandAPI::addConfigValue(PHANDLE, CONFIG_HW_DEBUG, Hyprlang::INT{0});
|
||||||
|
|
||||||
|
HyprlandAPI::reloadConfig();
|
||||||
|
|
||||||
return {"dynamic-cursors", "The most stupid cursor plugin.", "Virt", "1.1"};
|
return {"dynamic-cursors", "The most stupid cursor plugin.", "Virt", "1.1"};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue