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)

Reply via email to