vcl/inc/qt5/QtWidget.hxx | 2 + vcl/qt5/QtWidget.cxx | 55 ++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 56 insertions(+), 1 deletion(-)
New commits: commit efadd5210e56ba67f1b040dff4972fead6a56131 Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Mon Aug 14 08:10:21 2023 +0200 Commit: Michael Weghorn <m.wegh...@posteo.de> CommitDate: Mon Aug 14 10:07:46 2023 +0200 qt: Implement pinch/zoom gesture handling Subscribe to receive pinch gestures by calling `QWidget::grabGesture(Qt::PinchGesture)` and forward that as the corresponding `SalGestureZoomEvent`. From looking at what values the gtk implementation uses, `1 + pPinchGesture->totalScaleFactor()` seems to be a proper choice for the `SalGestureZoomEvent::mfScaleDelta` value. With this in place, zooming in and out of a Writer document with a two-finger zoom gesture works for me with the Qt-based VCL plugins in Writer on my laptop that has a touch screen. (It seems to be a bit more smooth with qt5/kf5 than with qt6, where doing several zoom gestures after each other sometimes requires to wait a bit before doing another gesture in order for that one to be processed properly.) Qt documentation for gestures: [1] Corresponding commit for gtk VCL plugins: commit f2bd19f6720239db228cd4388be8e928505c51b6 Author: Povilas Kanapickas <povi...@radix.lt> Date: Thu Aug 25 00:18:30 2022 +0300 vcl: implement touchpad zoom gesture support on gtk backend [1] https://doc.qt.io/qt-6/gestures-overview.html Change-Id: I288943d923463fee44314969648e03dca84c483f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/155649 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> diff --git a/vcl/inc/qt5/QtWidget.hxx b/vcl/inc/qt5/QtWidget.hxx index e61357198027..ca0165401e15 100644 --- a/vcl/inc/qt5/QtWidget.hxx +++ b/vcl/inc/qt5/QtWidget.hxx @@ -20,6 +20,7 @@ #pragma once #include <QtCore/QRect> +#include <QtWidgets/QGestureEvent> #include <QtWidgets/QWidget> #include <rtl/ustring.hxx> @@ -45,6 +46,7 @@ class QtWidget : public QWidget static void commitText(QtFrame&, const QString& aText); static void deleteReplacementText(QtFrame& rFrame, int nReplacementStart, int nReplacementLength); + static bool handleGestureEvent(QtFrame& rFrame, QGestureEvent* pGestureEvent); static bool handleKeyEvent(QtFrame&, const QWidget&, QKeyEvent*); static void handleMouseEnterLeaveEvents(const QtFrame&, QEvent*); static void fillSalAbstractMouseEvent(const QtFrame& rFrame, const QInputEvent* pQEvent, diff --git a/vcl/qt5/QtWidget.cxx b/vcl/qt5/QtWidget.cxx index 83ada7866f2b..5e7d1d56c464 100644 --- a/vcl/qt5/QtWidget.cxx +++ b/vcl/qt5/QtWidget.cxx @@ -516,6 +516,52 @@ void QtWidget::deleteReplacementText(QtFrame& rFrame, int nReplacementStart, int rFrame.CallCallback(SalEvent::DeleteSurroundingTextRequest, &aEvt); } +bool QtWidget::handleGestureEvent(QtFrame& rFrame, QGestureEvent* pGestureEvent) +{ + if (QGesture* pGesture = pGestureEvent->gesture(Qt::PinchGesture)) + { + if (!pGesture->hasHotSpot()) + { + pGestureEvent->ignore(); + return false; + } + + GestureEventZoomType eType = GestureEventZoomType::Begin; + switch (pGesture->state()) + { + case Qt::GestureStarted: + eType = GestureEventZoomType::Begin; + break; + case Qt::GestureUpdated: + eType = GestureEventZoomType::Update; + break; + case Qt::GestureFinished: + eType = GestureEventZoomType::End; + break; + case Qt::NoGesture: + case Qt::GestureCanceled: + default: + SAL_WARN("vcl.qt", "Unhandled pinch gesture state: " << pGesture->state()); + pGestureEvent->ignore(); + return false; + } + + QPinchGesture* pPinchGesture = static_cast<QPinchGesture*>(pGesture); + const QPointF aHotspot = pGesture->hotSpot(); + SalGestureZoomEvent aEvent; + aEvent.meEventType = eType; + aEvent.mnX = aHotspot.x(); + aEvent.mnY = aHotspot.y(); + aEvent.mfScaleDelta = 1 + pPinchGesture->totalScaleFactor(); + rFrame.CallCallback(SalEvent::GestureZoom, &aEvent); + pGestureEvent->accept(); + return true; + } + + pGestureEvent->ignore(); + return false; +} + bool QtWidget::handleKeyEvent(QtFrame& rFrame, const QWidget& rWidget, QKeyEvent* pEvent) { const bool bIsKeyPressed @@ -632,7 +678,12 @@ bool QtWidget::handleKeyEvent(QtFrame& rFrame, const QWidget& rWidget, QKeyEvent bool QtWidget::handleEvent(QtFrame& rFrame, QWidget& rWidget, QEvent* pEvent) { - if (pEvent->type() == QEvent::ShortcutOverride) + if (pEvent->type() == QEvent::Gesture) + { + QGestureEvent* pGestureEvent = static_cast<QGestureEvent*>(pEvent); + return handleGestureEvent(rFrame, pGestureEvent); + } + else if (pEvent->type() == QEvent::ShortcutOverride) { // ignore non-spontaneous QEvent::ShortcutOverride events, // since such an extra event is sent e.g. with Orca screen reader enabled, @@ -725,6 +776,8 @@ QtWidget::QtWidget(QtFrame& rFrame, Qt::WindowFlags f) setFocusPolicy(Qt::StrongFocus); else setFocusPolicy(Qt::ClickFocus); + + grabGesture(Qt::PinchGesture); } static ExtTextInputAttr lcl_MapUnderlineStyle(QTextCharFormat::UnderlineStyle us)