Commit ac30df57 authored by Steffen Hartleib's avatar Steffen Hartleib Committed by Nate Graham
Browse files

fix lagging zoom with touch in wayland

add a dynamically adjusted minimum wait time between two zoom events,
to reduce lag if you are zooming with touch.

BUG: 405945
parent b41631b2
......@@ -124,6 +124,7 @@ int main(int argc, char *argv[])
*/
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps, true);
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling, true);
QCoreApplication::setAttribute(Qt::AA_CompressHighFrequencyEvents, true);
QApplication app(argc, argv);
KLocalizedString::setApplicationDomain("gwenview");
......
......@@ -120,6 +120,7 @@ struct DocumentViewPrivate
QPointer<QDrag> mDrag;
Touch* mTouch;
int mMinTimeBetweenPinch;
void setCurrentAdapter(AbstractDocumentViewAdapter* adapter)
{
......@@ -736,19 +737,37 @@ qreal DocumentView::zoom() const
return d->mAdapter->zoom();
}
void DocumentView::setPinchParameter()
void DocumentView::setPinchParameter(qint64 timeStamp)
{
Q_UNUSED (timeStamp);
const qreal sensitivityModifier = 0.85;
const qreal rotationThreshold = 40;
d->mTouch->setZoomParameter(sensitivityModifier, zoom());
d->mTouch->setRotationThreshold (rotationThreshold);
d->mMinTimeBetweenPinch = 0;
}
void DocumentView::zoomGesture(qreal zoom, const QPoint& zoomCenter)
void DocumentView::zoomGesture(qreal zoom, const QPoint& zoomCenter, qint64 timeStamp)
{
if (zoom >= 0.0 && d->mAdapter->canZoom()) {
qint64 now = QDateTime::currentMSecsSinceEpoch();
const qint64 diff = now - timeStamp;
// in Wayland we can get the gesture event more frequently, to reduce CPU power we don't use every event
// to calculate and paint a new image (mMinTimeBetweenPinch).To determine the exact minimum waiting time between two
// pinch events, we use the difference between the time stamps. If the difference is too high we increase the minimum waiting time.
// The maximal waiting time is 40 milliseconds, this is equal to 25 frames per second.
if (diff > 40) {
d->mMinTimeBetweenPinch = (d->mMinTimeBetweenPinch * 2) + 1;
if (d->mMinTimeBetweenPinch > 40) {
d->mMinTimeBetweenPinch = 40;
}
}
if (diff > d->mMinTimeBetweenPinch) {
if (zoom >= 0.0 && d->mAdapter->canZoom()) {
d->setZoom(zoom, zoomCenter);
}
}
}
void DocumentView::rotationsGesture(qreal rotation)
......
......@@ -233,8 +233,8 @@ private Q_SLOTS:
void dragThumbnailLoaded(const KFileItem&, const QPixmap&);
void dragThumbnailLoadingFailed(const KFileItem&);
void setPinchParameter();
void zoomGesture(qreal newZoom, const QPoint& pos);
void setPinchParameter(qint64 timeStamp);
void zoomGesture(qreal newZoom, const QPoint& pos, qint64 timeStamp);
void rotationsGesture(qreal);
void swipeRight();
void swipeLeft();
......
......@@ -28,6 +28,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Cambridge, MA 02110-1301, USA
#include <QStyleHints>
#include <QGuiApplication>
#include <QGraphicsWidget>
#include <QDateTime>
#include "touch_helper.h"
......@@ -50,6 +51,7 @@ struct TouchPrivate
qreal mStartZoom;
qreal mZoomModifier;
qreal mRotationThreshold;
qint64 mLastTouchTimeStamp;
TapHoldAndMovingRecognizer* mTapHoldAndMovingRecognizer;
Qt::GestureType mTapHoldAndMoving;
......@@ -113,13 +115,15 @@ Touch::~Touch()
bool Touch::eventFilter(QObject*, QEvent* event)
{
if (event->type() == QEvent::TouchBegin) {
//move mouse cursor to touchpoint
QTouchEvent* touchEvent = static_cast<QTouchEvent*>(event);
d->mLastTouchTimeStamp = QDateTime::currentMSecsSinceEpoch();
const QPoint pos = Touch_Helper::simpleTouchPosition(event);
touchToMouseMove(pos, event, Qt::NoButton);
return true;
}
if (event->type() == QEvent::TouchUpdate) {
QTouchEvent* touchEvent = static_cast<QTouchEvent*>(event);
d->mLastTouchTimeStamp = QDateTime::currentMSecsSinceEpoch();
//because we suppress the making of mouse event through Qt, we need to make our own one finger panning
//but only if no TapHoldandMovingGesture is active (Drag and Drop action)
if (touchEvent->touchPoints().size() == 1 && !getTapHoldandMovingGestureActive()) {
......@@ -128,6 +132,10 @@ bool Touch::eventFilter(QObject*, QEvent* event)
}
return true;
}
if (event->type() == QEvent::TouchEnd) {
QTouchEvent* touchEvent = static_cast<QTouchEvent*>(event);
d->mLastTouchTimeStamp = QDateTime::currentMSecsSinceEpoch();
}
if (event->type() == QEvent::Gesture) {
gestureEvent(static_cast<QGestureEvent*>(event));
}
......@@ -144,7 +152,7 @@ bool Touch::gestureEvent(QGestureEvent* event)
if (checkPinchGesture(event)) {
ret = true;
emit pinchZoomTriggered(getZoomFromPinchGesture(event), positionGesture(event));
emit pinchZoomTriggered(getZoomFromPinchGesture(event), positionGesture(event), d->mLastTouchTimeStamp);
emit pinchRotateTriggered(getRotationFromPinchGesture(event));
}
......@@ -358,7 +366,7 @@ bool Touch::checkPinchGesture(QGestureEvent* event)
event->accept();
if (pinch->state() == Qt::GestureStarted) {
lastScaleFactor = 0;
emit pinchGestureStarted();
emit pinchGestureStarted(d->mLastTouchTimeStamp);
} else if (pinch->state() == Qt::GestureUpdated) {
//Because of a bug in Qt in a gesture event in a graphicsview, all gestures are trigger twice
//https://bugreports.qt.io/browse/QTBUG-13103
......
......@@ -83,9 +83,9 @@ signals:
void doubleTapTriggered();
void tapHoldAndMovingTriggered(const QPoint&);
void tapTriggered(const QPoint&);
void pinchGestureStarted();
void pinchGestureStarted(qint64);
void twoFingerTapTriggered();
void pinchZoomTriggered(qreal, const QPoint&);
void pinchZoomTriggered(qreal, const QPoint&, qint64);
void pinchRotateTriggered(qreal);
private:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment