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
This commit is contained in:
Yifan Zhu 2024-03-15 18:23:00 -07:00
parent 29135f188f
commit b6d315705b

View file

@ -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;
}