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)