vcl/inc/unx/gtk/gtkframe.hxx |    7 ++++++
 vcl/unx/gtk3/gtkframe.cxx    |   49 ++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 55 insertions(+), 1 deletion(-)

New commits:
commit f2bd19f6720239db228cd4388be8e928505c51b6
Author:     Povilas Kanapickas <povi...@radix.lt>
AuthorDate: Thu Aug 25 00:18:30 2022 +0300
Commit:     Caolán McNamara <caol...@redhat.com>
CommitDate: Fri Aug 26 22:32:03 2022 +0200

    vcl: implement touchpad zoom gesture support on gtk backend
    
    Note that this does not support touchscreen gestures. Enabling support
    for touchscreen gestures requires enabling GDK_TOUCH_MASK which has
    higher regression potential for touchscreen users, so it has not been
    done yet.
    
    Change-Id: I1baab36804230484394e638bf8bfb8c7a7ddabe0
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/138789
    Tested-by: Caolán McNamara <caol...@redhat.com>
    Reviewed-by: Caolán McNamara <caol...@redhat.com>

diff --git a/vcl/inc/unx/gtk/gtkframe.hxx b/vcl/inc/unx/gtk/gtkframe.hxx
index 57072134c414..52f256082832 100644
--- a/vcl/inc/unx/gtk/gtkframe.hxx
+++ b/vcl/inc/unx/gtk/gtkframe.hxx
@@ -348,6 +348,11 @@ class GtkSalFrame final : public SalFrame
 
     static gboolean     signalWindowState( GtkWidget*, GdkEvent*, gpointer );
 #endif
+
+    static bool         signalZoomBegin(GtkGesture*, GdkEventSequence*, 
gpointer);
+    static bool         signalZoomUpdate(GtkGesture*, GdkEventSequence*, 
gpointer);
+    static bool         signalZoomEnd(GtkGesture*, GdkEventSequence*, 
gpointer);
+
 #if !GTK_CHECK_VERSION(4, 0, 0)
     static gboolean     signalConfigure( GtkWidget*, GdkEventConfigure*, 
gpointer );
 #endif
@@ -434,6 +439,8 @@ public:
     guint                           m_nHudAwarenessId;
     std::vector<gulong>             m_aMouseSignalIds;
 
+    GtkGesture                     *m_pZoomGesture;
+
     void grabPointer(bool bGrab, bool bKeyboardAlso, bool bOwnerEvents);
 
     static GtkSalDisplay*  getDisplay();
diff --git a/vcl/unx/gtk3/gtkframe.cxx b/vcl/unx/gtk3/gtkframe.cxx
index dbd868c6fd6a..a387f9979d47 100644
--- a/vcl/unx/gtk3/gtkframe.cxx
+++ b/vcl/unx/gtk3/gtkframe.cxx
@@ -712,6 +712,9 @@ GtkSalFrame::~GtkSalFrame()
     GtkWidget *pEventWidget = getMouseEventWidget();
     for (auto handler_id : m_aMouseSignalIds)
         g_signal_handler_disconnect(G_OBJECT(pEventWidget), handler_id);
+
+    g_clear_object(&m_pZoomGesture);
+
 #if !GTK_CHECK_VERSION(4, 0, 0)
     if( m_pFixedContainer )
         gtk_widget_destroy( GTK_WIDGET( m_pFixedContainer ) );
@@ -1018,6 +1021,15 @@ void GtkSalFrame::InitCommon()
     gtk_widget_add_controller(pEventWidget, pScrollController);
 #endif
 
+    m_pZoomGesture = gtk_gesture_zoom_new(GTK_WIDGET(pEventWidget));
+    
gtk_event_controller_set_propagation_phase(GTK_EVENT_CONTROLLER(m_pZoomGesture),
+                                               GTK_PHASE_TARGET);
+    // Note that the default zoom gesture signal handler needs to run first to 
setup correct
+    // scale delta. Otherwise the first "begin" event will always contain 
scale delta of infinity.
+    g_signal_connect_after(m_pZoomGesture, "begin", 
G_CALLBACK(signalZoomBegin), this);
+    g_signal_connect_after(m_pZoomGesture, "update", 
G_CALLBACK(signalZoomUpdate), this);
+    g_signal_connect_after(m_pZoomGesture, "end", G_CALLBACK(signalZoomEnd), 
this);
+
     //Drop Target Stuff
 #if GTK_CHECK_VERSION(4,0,0)
     GtkDropTargetAsync* pDropTarget = gtk_drop_target_async_new(nullptr, 
GdkDragAction(GDK_ACTION_ALL));
@@ -1139,7 +1151,7 @@ void GtkSalFrame::InitCommon()
     gtk_widget_add_events( m_pWindow,
                            GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
                            GDK_POINTER_MOTION_MASK | 
GDK_POINTER_MOTION_HINT_MASK |
-                           GDK_SCROLL_MASK
+                           GDK_SCROLL_MASK | GDK_TOUCHPAD_GESTURE_MASK
                            );
 #endif
 
@@ -4515,6 +4527,41 @@ void GtkSalFrame::signalWindowState(GdkToplevel* 
pSurface, GParamSpec*, gpointer
 }
 #endif
 
+namespace
+{
+    bool handleSignalZoom(GtkGesture* gesture, GdkEventSequence* sequence, 
gpointer frame,
+                          GestureEventZoomType eEventType)
+    {
+        gdouble x = 0;
+        gdouble y = 0;
+        gtk_gesture_get_point(gesture, sequence, &x, &y);
+
+        SalGestureZoomEvent aEvent;
+        aEvent.meEventType = eEventType;
+        aEvent.mnX = x;
+        aEvent.mnY = y;
+        aEvent.mfScaleDelta = 
gtk_gesture_zoom_get_scale_delta(GTK_GESTURE_ZOOM(gesture));
+        GtkSalFrame* pThis = static_cast<GtkSalFrame*>(frame);
+        pThis->CallCallbackExc(SalEvent::GestureZoom, &aEvent);
+        return true;
+    }
+}
+
+bool GtkSalFrame::signalZoomBegin(GtkGesture* gesture, GdkEventSequence* 
sequence, gpointer frame)
+{
+    return handleSignalZoom(gesture, sequence, frame, 
GestureEventZoomType::Begin);
+}
+
+bool GtkSalFrame::signalZoomUpdate(GtkGesture* gesture, GdkEventSequence* 
sequence, gpointer frame)
+{
+    return handleSignalZoom(gesture, sequence, frame, 
GestureEventZoomType::Update);
+}
+
+bool GtkSalFrame::signalZoomEnd(GtkGesture* gesture, GdkEventSequence* 
sequence, gpointer frame)
+{
+    return handleSignalZoom(gesture, sequence, frame, 
GestureEventZoomType::End);
+}
+
 namespace
 {
     GdkDragAction VclToGdk(sal_Int8 dragOperation)

Reply via email to