wayland: Refactor the high-resolution scroll wheel step accumulator

This commit is contained in:
Vladimir Zolotopupov 2023-08-21 23:01:11 +03:00
parent 0ab928c9ac
commit 792ff84419
2 changed files with 45 additions and 26 deletions

View file

@ -133,6 +133,12 @@ void PointerInterfacePrivate::sendFrame()
}
}
bool PointerInterfacePrivate::AxisAccumulator::Axis::shouldReset(int newDirection) const
{
// Reset the accumulator if the delta has opposite sign.
return direction && ((direction < 0) != (newDirection < 0));
}
PointerInterface::PointerInterface(SeatInterface *seat)
: d(new PointerInterfacePrivate(this, seat))
{
@ -209,41 +215,28 @@ void PointerInterface::sendButton(quint32 button, PointerButtonState state, quin
}
}
static bool shouldResetAccumulator(int accumulator, int delta)
{
// Reset the accumulator if the delta has opposite sign.
return accumulator && (accumulator < 0 != delta < 0);
}
static void updateAccumulators(Qt::Orientation orientation, qreal delta, qint32 deltaV120, PointerInterfacePrivate *d, qint32 &valueAxisLowRes, qint32 &valueDiscrete)
{
qint32 *accumulatorV120;
qreal *accumulatorAxis;
const int newDirection = deltaV120 > 0 ? 1 : -1;
auto &accum = d->axisAccumulator.axis(orientation);
if (orientation == Qt::Horizontal) {
accumulatorV120 = &d->accumulatorV120.rx();
accumulatorAxis = &d->accumulatorAxis.rx();
} else {
accumulatorV120 = &d->accumulatorV120.ry();
accumulatorAxis = &d->accumulatorAxis.ry();
if (accum.shouldReset(newDirection)) {
accum.reset();
}
if (shouldResetAccumulator(*accumulatorV120, deltaV120)) {
*accumulatorV120 = 0;
*accumulatorAxis = 0;
}
accum.direction = newDirection;
*accumulatorAxis += delta;
*accumulatorV120 += deltaV120;
accum.axis += delta;
accum.axis120 += deltaV120;
// ±120 is a "wheel click"
valueDiscrete = *accumulatorV120 / 120;
*accumulatorV120 -= valueDiscrete * 120;
valueDiscrete = accum.axis120 / 120;
accum.axis120 -= valueDiscrete * 120;
if (valueDiscrete) {
// Accumulate the axis values to send to low-res clients
valueAxisLowRes = *accumulatorAxis;
*accumulatorAxis = 0;
valueAxisLowRes = accum.axis;
accum.axis = 0;
}
}

View file

@ -25,6 +25,33 @@ class RelativePointerV1Interface;
class PointerInterfacePrivate : public QtWaylandServer::wl_pointer
{
struct AxisAccumulator
{
struct Axis
{
bool shouldReset(int newDirection) const;
void reset()
{
axis120 = 0;
axis = 0;
}
qint32 axis120 = 0;
qreal axis = 0;
int direction = 0;
};
Axis &axis(Qt::Orientation orientation)
{
const int index = orientation == Qt::Orientation::Horizontal ? 0 : 1;
return m_axis[index];
}
private:
Axis m_axis[2];
};
public:
static PointerInterfacePrivate *get(PointerInterface *pointer);
@ -44,8 +71,7 @@ public:
std::unique_ptr<PointerPinchGestureV1Interface> pinchGesturesV1;
std::unique_ptr<PointerHoldGestureV1Interface> holdGesturesV1;
QPointF lastPosition;
QPointF accumulatorAxis;
QPoint accumulatorV120;
AxisAccumulator axisAccumulator;
void sendLeave(quint32 serial);
void sendEnter(const QPointF &parentSurfacePosition, quint32 serial);