vcl/inc/unx/gtk/gtkframe.hxx | 24 +++++++++--- vcl/unx/gtk3/gtkframe.cxx | 83 ++++++++++++++++++++++++++++++++----------- 2 files changed, 81 insertions(+), 26 deletions(-)
New commits: commit a161d8c2c7322cda720ec487cd31baae23f16546 Author: Caolán McNamara <caol...@redhat.com> AuthorDate: Tue May 11 12:12:42 2021 +0100 Commit: Caolán McNamara <caol...@redhat.com> CommitDate: Tue May 11 14:39:49 2021 +0200 gtk4: add basic scrolling support Change-Id: Ibe492ad1589d6ffeb8e8f18958e2b9cb2f0f9761 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/115397 Tested-by: Jenkins 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 4d440119a6b3..0f74ca131e3d 100644 --- a/vcl/inc/unx/gtk/gtkframe.hxx +++ b/vcl/inc/unx/gtk/gtkframe.hxx @@ -297,27 +297,39 @@ class GtkSalFrame final : public SalFrame void DrawingAreaMotion(int nEventX, int nEventY, guint32 nTime, guint nState); void DrawingAreaCrossing(SalEvent nEventType, int nEventX, int nEventY, guint32 nTime, guint nState); bool DrawingAreaKey(SalEvent nEventType, guint keyval, guint keycode, guint32 nTime, guint nState); + void DrawingAreaScroll(double delta_x, double delta_y, int nEventX, int nEventY, guint32 nTime, guint nState); #if GTK_CHECK_VERSION(4, 0, 0) static void signalMap( GtkWidget*, gpointer ); static void signalUnmap( GtkWidget*, gpointer ); + static gboolean signalDelete( GtkWidget*, gpointer ); + static void signalMotion(GtkEventControllerMotion *controller, double x, double y, gpointer); + + static gboolean signalScroll(GtkEventControllerScroll* pController, double delta_x, double delta_y, gpointer); + static void signalEnter(GtkEventControllerMotion *controller, double x, double y, gpointer); static void signalLeave(GtkEventControllerMotion *controller, gpointer); - static gboolean signalKeyPressed(GtkEventControllerKey *controller, guint keyval, guint keycode, GdkModifierType state, gpointer user_data); - static gboolean signalKeyReleased(GtkEventControllerKey *controller, guint keyval, guint keycode, GdkModifierType state, gpointer user_data); + + static gboolean signalKeyPressed(GtkEventControllerKey *controller, guint keyval, guint keycode, GdkModifierType state, gpointer); + static gboolean signalKeyReleased(GtkEventControllerKey *controller, guint keyval, guint keycode, GdkModifierType state, gpointer); #else static gboolean signalMap( GtkWidget*, GdkEvent*, gpointer ); static gboolean signalUnmap( GtkWidget*, GdkEvent*, gpointer ); + static gboolean signalDelete( GtkWidget*, GdkEvent*, gpointer ); + static gboolean signalMotion( GtkWidget*, GdkEventMotion*, gpointer ); + + static gboolean signalScroll( GtkWidget*, GdkEvent*, gpointer ); + + static gboolean signalCrossing( GtkWidget*, GdkEventCrossing*, gpointer ); + static gboolean signalKey( GtkWidget*, GdkEventKey*, gpointer ); #endif #if !GTK_CHECK_VERSION(4, 0, 0) static gboolean signalConfigure( GtkWidget*, GdkEventConfigure*, gpointer ); static gboolean signalWindowState( GtkWidget*, GdkEvent*, gpointer ); - static gboolean signalScroll( GtkWidget*, GdkEvent*, gpointer ); - static gboolean signalCrossing( GtkWidget*, GdkEventCrossing*, gpointer ); #endif static void signalDestroy( GtkWidget*, gpointer ); @@ -385,7 +397,9 @@ public: basegfx::B2IVector m_aFrameSize; DamageHandler m_aDamageHandler; std::vector<GdkEvent*> m_aPendingScrollEvents; +#if !GTK_CHECK_VERSION(4, 0, 0) Idle m_aSmoothScrollIdle; +#endif int m_nGrabLevel; bool m_bSalObjectSetPosSize; GtkSalFrame( SalFrame* pParent, SalFrameStyleFlags nStyle ); @@ -451,10 +465,10 @@ public: #if !GTK_CHECK_VERSION(4, 0, 0) void nopaint_container_resize_children(GtkContainer*); -#endif void LaunchAsyncScroll(GdkEvent const * pEvent); DECL_LINK(AsyncScroll, Timer *, void); +#endif virtual ~GtkSalFrame() override; diff --git a/vcl/unx/gtk3/gtkframe.cxx b/vcl/unx/gtk3/gtkframe.cxx index 1838652ebd3d..b98e5d2a75bf 100644 --- a/vcl/unx/gtk3/gtkframe.cxx +++ b/vcl/unx/gtk3/gtkframe.cxx @@ -654,8 +654,10 @@ void GtkSalFrame::InvalidateGraphics() GtkSalFrame::~GtkSalFrame() { +#if !GTK_CHECK_VERSION(4,0,0) m_aSmoothScrollIdle.Stop(); m_aSmoothScrollIdle.ClearInvokeHandler(); +#endif if (m_pDropTarget) { @@ -889,7 +891,9 @@ void GtkSalFrame::InitCommon() m_aDamageHandler.handle = this; m_aDamageHandler.damaged = ::damaged; +#if !GTK_CHECK_VERSION(4,0,0) m_aSmoothScrollIdle.SetInvokeHandler(LINK(this, GtkSalFrame, AsyncScroll)); +#endif m_pTopLevelGrid = GTK_GRID(gtk_grid_new()); #if !GTK_CHECK_VERSION(4,0,0) @@ -942,6 +946,8 @@ void GtkSalFrame::InitCommon() m_aMouseSignalIds.push_back(g_signal_connect( G_OBJECT(pEventWidget), "motion-notify-event", G_CALLBACK(signalMotion), this )); m_aMouseSignalIds.push_back(g_signal_connect( G_OBJECT(pEventWidget), "leave-notify-event", G_CALLBACK(signalCrossing), this )); m_aMouseSignalIds.push_back(g_signal_connect( G_OBJECT(pEventWidget), "enter-notify-event", G_CALLBACK(signalCrossing), this )); + + m_aMouseSignalIds.push_back(g_signal_connect( G_OBJECT(pEventWidget), "scroll-event", G_CALLBACK(signalScroll), this )); #else GtkGesture *pClick = gtk_gesture_click_new(); gtk_gesture_single_set_button(GTK_GESTURE_SINGLE(pClick), 0); @@ -954,6 +960,11 @@ void GtkSalFrame::InitCommon() g_signal_connect(pMotionController, "enter", G_CALLBACK(signalEnter), this); g_signal_connect(pMotionController, "leave", G_CALLBACK(signalLeave), this); gtk_widget_add_controller(pEventWidget, pMotionController); + + GtkEventController* pScrollController = gtk_event_controller_scroll_new(GTK_EVENT_CONTROLLER_SCROLL_BOTH_AXES); + g_signal_connect(pScrollController, "scroll", G_CALLBACK(signalScroll), this); + gtk_widget_add_controller(pEventWidget, pScrollController); + #endif #if !GTK_CHECK_VERSION(4,0,0) //Drop Target Stuff @@ -969,7 +980,6 @@ void GtkSalFrame::InitCommon() m_aMouseSignalIds.push_back(g_signal_connect( G_OBJECT(pEventWidget), "drag-failed", G_CALLBACK(signalDragFailed), this )); m_aMouseSignalIds.push_back(g_signal_connect( G_OBJECT(pEventWidget), "drag-data-delete", G_CALLBACK(signalDragDelete), this )); m_aMouseSignalIds.push_back(g_signal_connect( G_OBJECT(pEventWidget), "drag-data-get", G_CALLBACK(signalDragDataGet), this )); - m_aMouseSignalIds.push_back(g_signal_connect( G_OBJECT(pEventWidget), "scroll-event", G_CALLBACK(signalScroll), this )); #endif #if !GTK_CHECK_VERSION(4,0,0) @@ -3019,31 +3029,17 @@ void GtkSalFrame::LaunchAsyncScroll(GdkEvent const * pEvent) } #endif -IMPL_LINK_NOARG(GtkSalFrame, AsyncScroll, Timer *, void) +void GtkSalFrame::DrawingAreaScroll(double delta_x, double delta_y, int nEventX, int nEventY, guint32 nTime, guint nState) { -#if !GTK_CHECK_VERSION(4, 0, 0) - assert(!m_aPendingScrollEvents.empty()); - SalWheelMouseEvent aEvent; - GdkEvent* pEvent = m_aPendingScrollEvents.back(); - - aEvent.mnTime = pEvent->scroll.time; - aEvent.mnX = static_cast<sal_uLong>(pEvent->scroll.x); + aEvent.mnTime = nTime; + aEvent.mnX = nEventX; // --- RTL --- (mirror mouse pos) if (AllSettings::GetLayoutRTL()) aEvent.mnX = maGeometry.nWidth - 1 - aEvent.mnX; - aEvent.mnY = static_cast<sal_uLong>(pEvent->scroll.y); - aEvent.mnCode = GetMouseModCode( pEvent->scroll.state ); - - double delta_x(0.0), delta_y(0.0); - for (auto pSubEvent : m_aPendingScrollEvents) - { - delta_x += pSubEvent->scroll.delta_x; - delta_y += pSubEvent->scroll.delta_y; - gdk_event_free(pSubEvent); - } - m_aPendingScrollEvents.clear(); + aEvent.mnY = nEventY; + aEvent.mnCode = GetMouseModCode(nState); // rhbz#1344042 "Traditionally" in gtk3 we tool a single up/down event as // equating to 3 scroll lines and a delta of 120. So scale the delta here @@ -3070,9 +3066,34 @@ IMPL_LINK_NOARG(GtkSalFrame, AsyncScroll, Timer *, void) aEvent.mnScrollLines = std::abs(aEvent.mnDelta) / 40.0; CallCallbackExc(SalEvent::WheelMouse, &aEvent); } -#endif } +#if !GTK_CHECK_VERSION(4, 0, 0) +IMPL_LINK_NOARG(GtkSalFrame, AsyncScroll, Timer *, void) +{ + assert(!m_aPendingScrollEvents.empty()); + + SalWheelMouseEvent aEvent; + + GdkEvent* pEvent = m_aPendingScrollEvents.back(); + auto nEventX = pEvent->scroll.x; + auto nEventY = pEvent->scroll.y; + auto nTime = pEvent->scroll.time; + auto nState = pEvent->scroll.state; + + double delta_x(0.0), delta_y(0.0); + for (auto pSubEvent : m_aPendingScrollEvents) + { + delta_x += pSubEvent->scroll.delta_x; + delta_y += pSubEvent->scroll.delta_y; + gdk_event_free(pSubEvent); + } + m_aPendingScrollEvents.clear(); + + DrawingAreaScroll(delta_x, delta_y, nEventX, nEventY, nTime, nState); +} +#endif + #if !GTK_CHECK_VERSION(4, 0, 0) SalWheelMouseEvent GtkSalFrame::GetWheelEvent(const GdkEventScroll& rEvent) { @@ -3151,6 +3172,26 @@ gboolean GtkSalFrame::signalScroll(GtkWidget*, GdkEvent* pInEvent, gpointer fram return true; } +#else +gboolean GtkSalFrame::signalScroll(GtkEventControllerScroll* pController, double delta_x, double delta_y, gpointer frame) +{ + GtkSalFrame* pThis = static_cast<GtkSalFrame*>(frame); + + GdkEvent* pEvent = gtk_event_controller_get_current_event(GTK_EVENT_CONTROLLER(pController)); + GdkModifierType eState = gtk_event_controller_get_current_event_state(GTK_EVENT_CONTROLLER(pController)); + + auto nTime = gdk_event_get_time(pEvent); + + UpdateLastInputEventTime(nTime); + + double nEventX(0.0), nEventY(0.0); + gdk_event_get_position(pEvent, &nEventX, &nEventY); + + pThis->DrawingAreaScroll(delta_x, delta_y, nEventX, nEventY, nTime, eState); + + return true; +} + #endif void GtkSalFrame::gestureSwipe(GtkGestureSwipe* gesture, gdouble velocity_x, gdouble velocity_y, gpointer frame) _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits