From b6d315705bd4c84fc73b9921813d585802d1122e Mon Sep 17 00:00:00 2001 From: Yifan Zhu Date: Fri, 15 Mar 2024 18:23:00 -0700 Subject: [PATCH] pointer_input: make edgeBarrier behavior consistent on corners The pointer should cross a corner as soon as the movement in the barrier zone exceeds barrierWidth. Previously horizontal and vertical movements were separately considered, which made corners harder to cross compared to edges even when the separate corner barrier was disabled. CCBUG: 483651 --- src/pointer_input.cpp | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/pointer_input.cpp b/src/pointer_input.cpp index 5da860932f..e3e8893797 100644 --- a/src/pointer_input.cpp +++ b/src/pointer_input.cpp @@ -779,10 +779,6 @@ qreal PointerInputRedirection::edgeBarrier(EdgeBarrierType type) const QPointF PointerInputRedirection::applyEdgeBarrier(const QPointF &pos, const Output *currentOutput, std::chrono::microseconds time) { - auto softThreshold = [](qreal value, qreal threshold) { - return std::abs(value) < threshold ? 0 : value - (value > 0 ? threshold : -threshold); - }; - // optimization to avoid looping over all outputs if (exclusiveContains(currentOutput->geometry(), m_pos)) { m_movementInEdgeBarrier = QPointF(); @@ -800,17 +796,23 @@ QPointF PointerInputRedirection::applyEdgeBarrier(const QPointF &pos, const Outp std::chrono::microseconds timeDiff(time - m_lastMoveTime); qreal returnDistance = returnSpeed * timeDiff.count(); - m_movementInEdgeBarrier += (pos - newPos); - m_movementInEdgeBarrier.setX(softThreshold(m_movementInEdgeBarrier.x(), returnDistance)); - m_movementInEdgeBarrier.setY(softThreshold(m_movementInEdgeBarrier.y(), returnDistance)); + const auto euclideanLength = [](const QPointF &point) { + return std::sqrt(point.x() * point.x() + point.y() * point.y()); + }; + const auto shorten = [euclideanLength](const QPointF &point, const qreal distance) { + const qreal length = euclideanLength(point); + if (length <= distance) { + return QPointF(); + } + return point * (1 - distance / length); + }; - if (std::abs(m_movementInEdgeBarrier.x()) > barrierWidth) { - newPos.rx() += softThreshold(m_movementInEdgeBarrier.x(), barrierWidth); - m_movementInEdgeBarrier.setX(0); - } - if (std::abs(m_movementInEdgeBarrier.y()) > barrierWidth) { - newPos.ry() += softThreshold(m_movementInEdgeBarrier.y(), barrierWidth); - m_movementInEdgeBarrier.setY(0); + m_movementInEdgeBarrier += (pos - newPos); + m_movementInEdgeBarrier = shorten(m_movementInEdgeBarrier, returnDistance); + + if (euclideanLength(m_movementInEdgeBarrier) > barrierWidth) { + newPos += shorten(m_movementInEdgeBarrier, barrierWidth); + m_movementInEdgeBarrier = QPointF(); } return newPos; }