fix: ignore warps on modes and shake

This commit is contained in:
Virt 2024-08-25 22:58:55 +02:00
commit 55e8b316ce
14 changed files with 80 additions and 9 deletions

View file

@ -9,6 +9,7 @@
#define CONFIG_MODE "mode"
#define CONFIG_THRESHOLD "threshold"
#define CONFIG_HW_DEBUG "hw_debug"
#define CONFIG_IGNORE_WARPS "ignore_warps"
#define CONFIG_SHAKE "shake:enabled"
#define CONFIG_SHAKE_NEAREST "shake:nearest"

View file

@ -154,8 +154,10 @@ SP<Aquamarine::IBuffer> CDynamicCursors::renderHardware(CPointerManager* pointer
Debug::log(TRACE, "hardware cursor too big! {} > {}", pointers->currentCursorImage.size, maxSize);
return nullptr;
}
} else
} else {
maxSize = targetSize;
if (maxSize.x < 16 || maxSize.y < 16) maxSize = {16, 16}; // fix some annoying crashes in nest
}
if (!state->monitor->cursorSwapchain || maxSize != state->monitor->cursorSwapchain->currentOptions().size || state->monitor->cursorSwapchain->currentOptions().length != 3) {
@ -317,6 +319,9 @@ bool CDynamicCursors::setHardware(CPointerManager* pointers, SP<CPointerManager:
Handles cursor move events.
*/
void CDynamicCursors::onCursorMoved(CPointerManager* pointers) {
static auto* const* PSHAKE = (Hyprlang::INT* const*) getConfig(CONFIG_SHAKE);
static auto* const* PIGNORE_WARPS = (Hyprlang::INT* const*) getConfig(CONFIG_IGNORE_WARPS);
if (!pointers->hasCursor())
return;
@ -332,7 +337,18 @@ void CDynamicCursors::onCursorMoved(CPointerManager* pointers) {
m->output->moveCursor(CURSORPOS);
}
// ignore warp
if (!isMove && **PIGNORE_WARPS) {
auto mode = this->currentMode();
if (mode) mode->warp(lastPos, pointers->pointerPos);
if (**PSHAKE) shake.warp(lastPos, pointers->pointerPos);
}
calculate(MOVE);
isMove = false;
lastPos = pointers->pointerPos;
}
void CDynamicCursors::setShape(const std::string& shape) {
@ -426,3 +442,7 @@ void CDynamicCursors::calculate(EModeUpdate type) {
}
}
}
void CDynamicCursors::setMove() {
isMove = true;
}

View file

@ -35,12 +35,16 @@ class CDynamicCursors {
/* hook on setCursorSoftware */
void unsetShape();
/* hook on move, indicate that next onCursorMoved is actual move */
void setMove();
private:
SP<CEventLoopTimer> tick;
// current state of the cursor
SModeResult resultMode;
double resultShake;
Vector2D lastPos; // used for warp compensation
SModeResult resultShown;
@ -57,6 +61,9 @@ class CDynamicCursors {
// shake
CShake shake;
/* is set true if a genuine move is being performed, and will be reset to false after onCursorMoved */
bool isMove = false;
// calculates the current angle of the cursor, and changes the cursor shape
void calculate(EModeUpdate type);
};

View file

@ -67,6 +67,13 @@ void hkSetCursorSurface(void* thisptr, SP<CWLSurface> surf, const Vector2D& hots
(*(origSetCursorSurface)g_pSetCursorSurfaceHook->m_pOriginal)(thisptr, surf, hotspot);
}
typedef void (*origMove)(void*, const Vector2D&);
inline CFunctionHook* g_pMoveHook = nullptr;
void hkMove(void* thisptr, const Vector2D& deltaLogical) {
if (isEnabled()) g_pDynamicCursors->setMove();
(*(origMove)g_pMoveHook->m_pOriginal)(thisptr, deltaLogical);
}
/* hooks a function hook */
CFunctionHook* hook(std::string name, std::string object, void* function) {
auto names = HyprlandAPI::findFunctionsByName(PHANDLE, name);
@ -126,6 +133,7 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) {
addShapeConfig(CONFIG_ROTATE_OFFSET, 0.0f);
addConfig(CONFIG_HW_DEBUG, false);
addConfig(CONFIG_IGNORE_WARPS, true);
addRulesConfig();
finishConfig();
@ -140,6 +148,7 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) {
g_pRenderHWCursorBufferHook = hook("renderHWCursorBuffer", "CPointerManager", (void*) &hkRenderHWCursorBuffer);
g_pSetHWCursorBufferHook = hook("setHWCursorBuffer", "CPointerManager", (void*) &hkSetHWCursorBuffer);
g_pOnCursorMovedHook = hook("onCursorMoved", "CPointerManager", (void*) &hkOnCursorMoved);
g_pMoveHook = hook("moveER", "CPointerManager", (void*) &hkMove); // this `ER` makes it faster because `move` is very generic
g_pSetCursorFromNameHook = hook("setCursorFromName", "CCursorManager", (void*) &hkSetCursorFromName);
g_pSetCursorSurfaceHook = hook("setCursorSurface", "CCursorManager", (void*) &hkSetCursorSurface);

View file

@ -11,4 +11,6 @@ class IMode {
virtual EModeUpdate strategy() = 0;
/* updates the calculations and returns the new angle */
virtual SModeResult update(Vector2D pos) = 0;
/* called on warp, an update will be sent afterwards (probably) */
virtual void warp(Vector2D old, Vector2D pos) = 0;
};

View file

@ -45,3 +45,7 @@ SModeResult CModeRotate::update(Vector2D pos) {
return result;
}
void CModeRotate::warp(Vector2D old, Vector2D pos) {
end += (pos - old);
}

View file

@ -9,6 +9,7 @@ class CModeRotate : public IMode {
public:
virtual EModeUpdate strategy();
virtual SModeResult update(Vector2D pos);
virtual void warp(Vector2D old, Vector2D pos);
private:

View file

@ -40,3 +40,10 @@ SModeResult CModeStretch::update(Vector2D pos) {
return result;
}
void CModeStretch::warp(Vector2D old, Vector2D pos) {
auto delta = pos - old;
for (auto& sample : samples)
sample += delta;
}

View file

@ -6,6 +6,7 @@ class CModeStretch : public IMode {
public:
virtual EModeUpdate strategy();
virtual SModeResult update(Vector2D pos);
virtual void warp(Vector2D old, Vector2D pos);
private:

View file

@ -30,3 +30,10 @@ SModeResult CModeTilt::update(Vector2D pos) {
result.rotation = activation(function, limit, speed) * (PI / 3); // 120° in both directions
return result;
}
void CModeTilt::warp(Vector2D old, Vector2D pos) {
auto delta = pos - old;
for (auto& sample : samples)
sample += delta;
}

View file

@ -6,6 +6,7 @@ class CModeTilt : public IMode {
public:
virtual EModeUpdate strategy();
virtual SModeResult update(Vector2D pos);
virtual void warp(Vector2D old, Vector2D pos);
private:

View file

@ -111,3 +111,10 @@ double CShake::update(Vector2D pos) {
return this->zoom.value();
}
void CShake::warp(Vector2D old, Vector2D pos) {
auto delta = pos - old;
for (auto& sample : samples)
sample += delta;
}

View file

@ -16,6 +16,8 @@ class CShake {
/* calculates the new zoom factor for the current pos */
double update(Vector2D pos);
/* called when a cursor warp has happened (to avoid magnifying on warps) */
void warp(Vector2D old, Vector2D pos);
private:
/* tracks whether the current shake has already been announced in the ipc */