input: Fix VRR for constrained cursors (#6877)
This commit is contained in:
parent
f5db483973
commit
ee8116ac5d
12 changed files with 100 additions and 17 deletions
|
|
@ -259,7 +259,7 @@ void CAnimationManager::tick() {
|
|||
|
||||
// manually schedule a frame
|
||||
if (PMONITOR)
|
||||
g_pCompositor->scheduleFrameForMonitor(PMONITOR, Aquamarine::IOutput::AQ_SCHEDULE_CURSOR_SHAPE);
|
||||
g_pCompositor->scheduleFrameForMonitor(PMONITOR, Aquamarine::IOutput::AQ_SCHEDULE_ANIMATION);
|
||||
}
|
||||
|
||||
// do it here, because if this alters the animation vars deque we would be in trouble above.
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#include "../Compositor.hpp"
|
||||
#include "../config/ConfigValue.hpp"
|
||||
#include "../protocols/PointerGestures.hpp"
|
||||
#include "../protocols/RelativePointer.hpp"
|
||||
#include "../protocols/FractionalScale.hpp"
|
||||
#include "../protocols/IdleNotify.hpp"
|
||||
#include "../protocols/core/Compositor.hpp"
|
||||
|
|
@ -328,7 +329,7 @@ void CPointerManager::onCursorMoved() {
|
|||
continue;
|
||||
|
||||
const auto CURSORPOS = getCursorPosForMonitor(m);
|
||||
m->output->moveCursor(CURSORPOS);
|
||||
m->output->moveCursor(CURSORPOS, m->shouldSkipScheduleFrameOnMouseEvent());
|
||||
}
|
||||
|
||||
if (recalc)
|
||||
|
|
@ -342,7 +343,7 @@ bool CPointerManager::attemptHardwareCursor(SP<CPointerManager::SMonitorPointerS
|
|||
return false;
|
||||
|
||||
const auto CURSORPOS = getCursorPosForMonitor(state->monitor.lock());
|
||||
state->monitor->output->moveCursor(CURSORPOS);
|
||||
state->monitor->output->moveCursor(CURSORPOS, state->monitor->shouldSkipScheduleFrameOnMouseEvent());
|
||||
|
||||
auto texture = getCurrentCursorTexture();
|
||||
|
||||
|
|
@ -385,7 +386,8 @@ bool CPointerManager::setHWCursorBuffer(SP<SMonitorPointerState> state, SP<Aquam
|
|||
|
||||
state->cursorFrontBuffer = buf;
|
||||
|
||||
g_pCompositor->scheduleFrameForMonitor(state->monitor.get(), Aquamarine::IOutput::AQ_SCHEDULE_CURSOR_SHAPE);
|
||||
if (!state->monitor->shouldSkipScheduleFrameOnMouseEvent())
|
||||
g_pCompositor->scheduleFrameForMonitor(state->monitor.get(), Aquamarine::IOutput::AQ_SCHEDULE_CURSOR_SHAPE);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -676,8 +678,11 @@ void CPointerManager::warpTo(const Vector2D& logical) {
|
|||
damageIfSoftware();
|
||||
|
||||
pointerPos = closestValid(logical);
|
||||
recheckEnteredOutputs();
|
||||
onCursorMoved();
|
||||
|
||||
if (!g_pInputManager->isLocked()) {
|
||||
recheckEnteredOutputs();
|
||||
onCursorMoved();
|
||||
}
|
||||
|
||||
damageIfSoftware();
|
||||
}
|
||||
|
|
@ -859,7 +864,14 @@ void CPointerManager::attachPointer(SP<IPointer> pointer) {
|
|||
});
|
||||
|
||||
listener->frame = pointer->pointerEvents.frame.registerListener([this] (std::any e) {
|
||||
g_pSeatManager->sendPointerFrame();
|
||||
bool shouldSkip = false;
|
||||
if (!g_pSeatManager->mouse.expired() && g_pInputManager->isLocked()) {
|
||||
auto PMONITOR = g_pCompositor->m_pLastMonitor.get();
|
||||
shouldSkip = PMONITOR && PMONITOR->shouldSkipScheduleFrameOnMouseEvent();
|
||||
}
|
||||
g_pSeatManager->isPointerFrameSkipped = shouldSkip;
|
||||
if (!g_pSeatManager->isPointerFrameSkipped)
|
||||
g_pSeatManager->sendPointerFrame();
|
||||
});
|
||||
|
||||
listener->swipeBegin = pointer->pointerEvents.swipeBegin.registerListener([this] (std::any e) {
|
||||
|
|
@ -1080,3 +1092,22 @@ void CPointerManager::damageCursor(SP<CMonitor> pMonitor) {
|
|||
Vector2D CPointerManager::cursorSizeLogical() {
|
||||
return currentCursorImage.size / currentCursorImage.scale;
|
||||
}
|
||||
|
||||
void CPointerManager::storeMovement(uint64_t time, const Vector2D& delta, const Vector2D& deltaUnaccel) {
|
||||
storedTime = time;
|
||||
storedDelta += delta;
|
||||
storedUnaccel += deltaUnaccel;
|
||||
}
|
||||
|
||||
void CPointerManager::setStoredMovement(uint64_t time, const Vector2D& delta, const Vector2D& deltaUnaccel) {
|
||||
storedTime = time;
|
||||
storedDelta = delta;
|
||||
storedUnaccel = deltaUnaccel;
|
||||
}
|
||||
|
||||
void CPointerManager::sendStoredMovement() {
|
||||
PROTO::relativePointer->sendRelativeMotion((uint64_t)storedTime * 1000, storedDelta, storedUnaccel);
|
||||
storedTime = 0;
|
||||
storedDelta = Vector2D{};
|
||||
storedUnaccel = Vector2D{};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,6 +61,9 @@ class CPointerManager {
|
|||
//
|
||||
Vector2D position();
|
||||
Vector2D cursorSizeLogical();
|
||||
void storeMovement(uint64_t time, const Vector2D& delta, const Vector2D& deltaUnaccel);
|
||||
void setStoredMovement(uint64_t time, const Vector2D& delta, const Vector2D& deltaUnaccel);
|
||||
void sendStoredMovement();
|
||||
|
||||
void recheckEnteredOutputs();
|
||||
|
||||
|
|
@ -154,6 +157,10 @@ class CPointerManager {
|
|||
|
||||
Vector2D pointerPos = {0, 0};
|
||||
|
||||
uint64_t storedTime = 0;
|
||||
Vector2D storedDelta = {0, 0};
|
||||
Vector2D storedUnaccel = {0, 0};
|
||||
|
||||
struct SMonitorPointerState {
|
||||
SMonitorPointerState(SP<CMonitor> m) : monitor(m) {}
|
||||
~SMonitorPointerState() {}
|
||||
|
|
|
|||
|
|
@ -128,6 +128,9 @@ class CSeatManager {
|
|||
void setGrab(SP<CSeatGrab> grab); // nullptr removes
|
||||
SP<CSeatGrab> seatGrab;
|
||||
|
||||
bool isPointerFrameSkipped = false;
|
||||
bool isPointerFrameCommit = false;
|
||||
|
||||
private:
|
||||
struct SSeatResourceContainer {
|
||||
SSeatResourceContainer(SP<CWLSeatResource>);
|
||||
|
|
|
|||
|
|
@ -87,6 +87,11 @@ void CInputManager::onMouseMoved(IPointer::SMotionEvent e) {
|
|||
|
||||
const auto DELTA = *PNOACCEL == 1 ? e.unaccel : e.delta;
|
||||
|
||||
if (g_pSeatManager->isPointerFrameSkipped)
|
||||
g_pPointerManager->storeMovement((uint64_t)e.timeMs, DELTA, e.unaccel);
|
||||
else
|
||||
g_pPointerManager->setStoredMovement((uint64_t)e.timeMs, DELTA, e.unaccel);
|
||||
|
||||
PROTO::relativePointer->sendRelativeMotion((uint64_t)e.timeMs * 1000, DELTA, e.unaccel);
|
||||
|
||||
g_pPointerManager->move(DELTA);
|
||||
|
|
@ -167,7 +172,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
|||
|
||||
m_vLastCursorPosFloored = MOUSECOORDSFLOORED;
|
||||
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromCursor();
|
||||
const auto PMONITOR = isLocked() && g_pCompositor->m_pLastMonitor ? g_pCompositor->m_pLastMonitor.get() : g_pCompositor->getMonitorFromCursor();
|
||||
|
||||
// this can happen if there are no displays hooked up to Hyprland
|
||||
if (PMONITOR == nullptr)
|
||||
|
|
@ -184,9 +189,9 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
|||
// constraints
|
||||
if (!g_pSeatManager->mouse.expired() && isConstrained()) {
|
||||
const auto SURF = CWLSurface::fromResource(g_pCompositor->m_pLastFocus.lock());
|
||||
const auto CONSTRAINT = SURF->constraint();
|
||||
const auto CONSTRAINT = SURF ? SURF->constraint() : nullptr;
|
||||
|
||||
if (SURF && CONSTRAINT) {
|
||||
if (CONSTRAINT) {
|
||||
if (CONSTRAINT->isLocked()) {
|
||||
const auto HINT = CONSTRAINT->logicPositionHint();
|
||||
g_pCompositor->warpCursorTo(HINT, true);
|
||||
|
|
@ -1428,6 +1433,16 @@ bool CInputManager::isConstrained() {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool CInputManager::isLocked() {
|
||||
if (!isConstrained())
|
||||
return false;
|
||||
|
||||
const auto SURF = CWLSurface::fromResource(g_pCompositor->m_pLastFocus.lock());
|
||||
const auto CONSTRAINT = SURF ? SURF->constraint() : nullptr;
|
||||
|
||||
return CONSTRAINT && CONSTRAINT->isLocked();
|
||||
}
|
||||
|
||||
void CInputManager::updateCapabilities() {
|
||||
uint32_t caps = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@ class CInputManager {
|
|||
|
||||
void unconstrainMouse();
|
||||
bool isConstrained();
|
||||
bool isLocked();
|
||||
|
||||
Vector2D getMouseCoordsInternal();
|
||||
void refocus();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue