From 1338cbd94338a4829f01e2c9555169a608b0726a Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Mon, 18 Nov 2019 11:38:12 -0700 Subject: [PATCH] Fix touch event timeout on mac and allow camera orbit using the touchpad on windows --- .../src/input-plugins/KeyboardMouseDevice.cpp | 60 ++++++++++++++++--- .../src/input-plugins/KeyboardMouseDevice.h | 3 + 2 files changed, 54 insertions(+), 9 deletions(-) diff --git a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp index 50c9f6aa3b..c1e937ac72 100755 --- a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp +++ b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp @@ -127,12 +127,53 @@ void KeyboardMouseDevice::mouseMoveEvent(QMouseEvent* event) { } } -void KeyboardMouseDevice::wheelEvent(QWheelEvent* event) { - auto currentMove = event->angleDelta() / 120.0f; - _inputDevice->_axisStateMap[_inputDevice->makeInput(MOUSE_AXIS_WHEEL_X_POS).getChannel()].value = currentMove.x() > 0 ? currentMove.x() : 0; - _inputDevice->_axisStateMap[_inputDevice->makeInput(MOUSE_AXIS_WHEEL_X_NEG).getChannel()].value = currentMove.x() < 0 ? -currentMove.x() : 0; - _inputDevice->_axisStateMap[_inputDevice->makeInput(MOUSE_AXIS_WHEEL_Y_POS).getChannel()].value = currentMove.y() > 0 ? currentMove.y() : 0; - _inputDevice->_axisStateMap[_inputDevice->makeInput(MOUSE_AXIS_WHEEL_Y_NEG).getChannel()].value = currentMove.y() < 0 ? -currentMove.y() : 0; +bool KeyboardMouseDevice::isWheelByTouchPad(QWheelEvent* event) { + QPoint delta = event->angleDelta(); + int deltaValueX = abs(delta.manhattanLength()); + int deltaValueY = abs(delta.manhattanLength()); + const int MAX_WHEEL_DELTA_REPEAT = 20; + const int COMMON_WHEEL_DELTA_VALUE = 120; + if (deltaValueX != 0) { + if (abs(_lastWheelDelta.x()) == deltaValueX) { + _wheelDeltaRepeatCount.setX(_wheelDeltaRepeatCount.x() + 1); + } else { + _wheelDeltaRepeatCount.setX(0); + } + return deltaValueX != COMMON_WHEEL_DELTA_VALUE && _wheelDeltaRepeatCount.x() < MAX_WHEEL_DELTA_REPEAT; + } + if (deltaValueY != 0) { + if (abs(_lastWheelDelta.y()) == deltaValueY) { + _wheelDeltaRepeatCount.setY(_wheelDeltaRepeatCount.y() + 1); + } else { + _wheelDeltaRepeatCount.setY(0); + } + return deltaValueY != COMMON_WHEEL_DELTA_VALUE && _wheelDeltaRepeatCount.y() < MAX_WHEEL_DELTA_REPEAT; + } + return false; +} + +void KeyboardMouseDevice::wheelEvent(QWheelEvent* event) { + if (isWheelByTouchPad(event)) { + // Check for horizontal and vertical scroll not triggered by the mouse. + // These are most likelly triggered by two fingers gesture on touchpad for windows. + QPoint delta = event->angleDelta(); + float deltaX = (float)delta.x(); + float deltaY = (float)delta.y(); + _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_X_POS).getChannel()].value = (deltaX > 0 ? deltaX : 0.0f); + _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_X_NEG).getChannel()].value = (deltaX < 0 ? -deltaX : 0.0f); + // Y mouse is inverted positive is pointing up the screen + const float WHEEL_Y_ATTENUATION = 0.02f; + _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_Y_POS).getChannel()].value = (deltaY < 0 ? -WHEEL_Y_ATTENUATION * deltaY : 0.0f); + _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_Y_NEG).getChannel()].value = (deltaY > 0 ? WHEEL_Y_ATTENUATION * deltaY : 0.0f); + } else { + auto currentMove = event->angleDelta() / 120.0f; + float currentMoveX = (float)currentMove.x(); + float currentMoveY = (float)currentMove.y(); + _inputDevice->_axisStateMap[_inputDevice->makeInput(MOUSE_AXIS_WHEEL_X_POS).getChannel()].value = currentMoveX > 0 ? currentMoveX : 0.0f; + _inputDevice->_axisStateMap[_inputDevice->makeInput(MOUSE_AXIS_WHEEL_X_NEG).getChannel()].value = currentMoveX < 0 ? -currentMoveX : 0.0f; + _inputDevice->_axisStateMap[_inputDevice->makeInput(MOUSE_AXIS_WHEEL_Y_POS).getChannel()].value = currentMoveY > 0 ? currentMoveY : 0.0f; + _inputDevice->_axisStateMap[_inputDevice->makeInput(MOUSE_AXIS_WHEEL_Y_NEG).getChannel()].value = currentMoveY < 0 ? -currentMoveY : 0.0f; + } } glm::vec2 evalAverageTouchPoints(const QList& points) { @@ -156,10 +197,11 @@ void KeyboardMouseDevice::touchGestureEvent(const QGestureEvent* event) { break; case Qt::GestureUpdated: { + const float PINCH_DELTA_STEP = 0.05f; qreal totalScaleFactor = pinchGesture->totalScaleFactor(); qreal scaleFactorDelta = totalScaleFactor - _lastTotalScaleFactor; - _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_GESTURE_PINCH_POS).getChannel()].value = (float) (scaleFactorDelta > 0 ? scaleFactorDelta : 0.0f); - _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_GESTURE_PINCH_NEG).getChannel()].value = (float) (scaleFactorDelta < 0 ? -scaleFactorDelta : 0.0f); + _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_GESTURE_PINCH_POS).getChannel()].value = scaleFactorDelta > 0.0 ? PINCH_DELTA_STEP : 0.0f; + _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_GESTURE_PINCH_NEG).getChannel()].value = scaleFactorDelta < 0.0 ? PINCH_DELTA_STEP : 0.0f; _lastTotalScaleFactor = totalScaleFactor; break; } @@ -198,7 +240,7 @@ void KeyboardMouseDevice::touchUpdateEvent(const QTouchEvent* event) { _lastTouchTime = _clock.now(); if (!_isTouching) { - _isTouching = event->touchPointStates().testFlag(Qt::TouchPointPressed); + _isTouching = true; } else { auto currentMove = currentPos - _lastTouch; _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_X_POS).getChannel()].value = (currentMove.x > 0 ? currentMove.x : 0.0f); diff --git a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h index f53190b6ad..4286ced477 100644 --- a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h +++ b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h @@ -90,6 +90,7 @@ public: void touchUpdateEvent(const QTouchEvent* event); void wheelEvent(QWheelEvent* event); + bool isWheelByTouchPad(QWheelEvent* event); static void enableTouch(bool enableTouch) { _enableTouch = enableTouch; } @@ -135,6 +136,8 @@ protected: std::chrono::high_resolution_clock::time_point _lastTouchTime; static bool _enableTouch; + QPoint _lastWheelDelta; + QPoint _wheelDeltaRepeatCount; private: void updateDeltaAxisValue(int channel, float value);