From bda6bce91555861f604a74b8f3d6cc6cd35c11c4 Mon Sep 17 00:00:00 2001 From: Caolán McNamara Date: Thu, 23 Jun 2016 17:32:11 +0100 Subject: Resolves: rhbz#1349501 gtk3: smooth scrolling events can be disabled... by the user with GDK_CORE_DEVICE_EVENTS=1, and so manage to disable their wheel scrolling (cherry picked from commit 7dfd50f947671d79b9119f10259857700d5728d8) Change-Id: I7df63f738983c90dea75b9f43a36133910446aba Resolves: rhbz#1349501 gtk3: smooth scrolling events can be disabled... better fix, if we listen to the eventbox we get either SMOOTH scrolling or not smooth events, not both. We get SMOOTH when supported, and not if not supported so no need to reintroduce the miserable hack, which doesn't work under wayland anyway Change-Id: I993e71d3553322425a506cd93d812efe081bf3c9 (cherry picked from commit 053a843bccaef2d2323be3ddff6217c592a4c5db) Reviewed-on: https://gerrit.libreoffice.org/26646 Tested-by: Jenkins Reviewed-by: Michael Meeks --- vcl/inc/unx/gtk/gtkframe.hxx | 2 +- vcl/unx/gtk/gtksalframe.cxx | 3 +- vcl/unx/gtk3/gtk3gtkframe.cxx | 112 +++++++++++++++++++++++++++--------------- 3 files changed, 75 insertions(+), 42 deletions(-) diff --git a/vcl/inc/unx/gtk/gtkframe.hxx b/vcl/inc/unx/gtk/gtkframe.hxx index eaa222f56e33..3b81c5409c71 100644 --- a/vcl/inc/unx/gtk/gtkframe.hxx +++ b/vcl/inc/unx/gtk/gtkframe.hxx @@ -277,7 +277,7 @@ class GtkSalFrame : public SalFrame static gboolean signalKey( GtkWidget*, GdkEventKey*, gpointer ); static gboolean signalDelete( GtkWidget*, GdkEvent*, gpointer ); static gboolean signalWindowState( GtkWidget*, GdkEvent*, gpointer ); - static gboolean signalScroll( GtkWidget*, GdkEvent*, gpointer ); + static gboolean signalScroll( GtkWidget*, GdkEventScroll* pEvent, gpointer ); static gboolean signalCrossing( GtkWidget*, GdkEventCrossing*, gpointer ); static gboolean signalVisibility( GtkWidget*, GdkEventVisibility*, gpointer ); static void signalDestroy( GtkWidget*, gpointer ); diff --git a/vcl/unx/gtk/gtksalframe.cxx b/vcl/unx/gtk/gtksalframe.cxx index 95fd581a42b8..84615c88a114 100644 --- a/vcl/unx/gtk/gtksalframe.cxx +++ b/vcl/unx/gtk/gtksalframe.cxx @@ -2855,10 +2855,9 @@ gboolean GtkSalFrame::signalButton( GtkWidget*, GdkEventButton* pEvent, gpointer return true; } -gboolean GtkSalFrame::signalScroll( GtkWidget*, GdkEvent* pEvent, gpointer frame ) +gboolean GtkSalFrame::signalScroll( GtkWidget*, GdkEventScroll* pSEvent, gpointer frame ) { GtkSalFrame* pThis = static_cast(frame); - GdkEventScroll* pSEvent = reinterpret_cast(pEvent); static sal_uLong nLines = 0; if( ! nLines ) diff --git a/vcl/unx/gtk3/gtk3gtkframe.cxx b/vcl/unx/gtk3/gtk3gtkframe.cxx index 6363815669a0..1c579912625e 100644 --- a/vcl/unx/gtk3/gtk3gtkframe.cxx +++ b/vcl/unx/gtk3/gtk3gtkframe.cxx @@ -1039,6 +1039,7 @@ 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 )); g_signal_connect( G_OBJECT(m_pFixedContainer), "draw", G_CALLBACK(signalDraw), this ); g_signal_connect( G_OBJECT(m_pFixedContainer), "size-allocate", G_CALLBACK(sizeAllocated), this ); @@ -1064,7 +1065,6 @@ void GtkSalFrame::InitCommon() g_signal_connect( G_OBJECT(m_pWindow), "key-release-event", G_CALLBACK(signalKey), this ); g_signal_connect( G_OBJECT(m_pWindow), "delete-event", G_CALLBACK(signalDelete), this ); g_signal_connect( G_OBJECT(m_pWindow), "window-state-event", G_CALLBACK(signalWindowState), this ); - g_signal_connect( G_OBJECT(m_pWindow), "scroll-event", G_CALLBACK(signalScroll), this ); g_signal_connect( G_OBJECT(m_pWindow), "leave-notify-event", G_CALLBACK(signalCrossing), this ); g_signal_connect( G_OBJECT(m_pWindow), "enter-notify-event", G_CALLBACK(signalCrossing), this ); g_signal_connect( G_OBJECT(m_pWindow), "visibility-notify-event", G_CALLBACK(signalVisibility), this ); @@ -2559,54 +2559,88 @@ gboolean GtkSalFrame::signalButton( GtkWidget*, GdkEventButton* pEvent, gpointer return true; } -gboolean GtkSalFrame::signalScroll( GtkWidget*, GdkEvent* pEvent, gpointer frame ) +gboolean GtkSalFrame::signalScroll( GtkWidget*, GdkEventScroll* pEvent, gpointer frame ) { - GdkEventScroll* pSEvent = reinterpret_cast(pEvent); - if (pSEvent->direction != GDK_SCROLL_SMOOTH) - return false; - GtkSalFrame* pThis = static_cast(frame); SalWheelMouseEvent aEvent; - aEvent.mnTime = pSEvent->time; - aEvent.mnX = (sal_uLong)pSEvent->x; + aEvent.mnTime = pEvent->time; + aEvent.mnX = (sal_uLong)pEvent->x; // --- RTL --- (mirror mouse pos) if (AllSettings::GetLayoutRTL()) aEvent.mnX = pThis->maGeometry.nWidth - 1 - aEvent.mnX; - aEvent.mnY = (sal_uLong)pSEvent->y; - aEvent.mnCode = GetMouseModCode( pSEvent->state ); - - // 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 - // by 120 where a single mouse wheel click is an incoming delta_x of 1 - // and divide that by 40 to get the number of scrollines - if (pSEvent->delta_x != 0.0) - { - aEvent.mnDelta = -pSEvent->delta_x * 120; - aEvent.mnNotchDelta = aEvent.mnDelta < 0 ? -1 : +1; - if (aEvent.mnDelta == 0) - aEvent.mnDelta = aEvent.mnNotchDelta; - aEvent.mbHorz = true; - aEvent.mnScrollLines = std::abs(aEvent.mnDelta) / 40; - if (aEvent.mnScrollLines == 0) - aEvent.mnScrollLines = 1; - - pThis->CallCallback(SALEVENT_WHEELMOUSE, &aEvent); - } + aEvent.mnY = (sal_uLong)pEvent->y; + aEvent.mnCode = GetMouseModCode( pEvent->state ); - if (pSEvent->delta_y != 0.0) + switch (pEvent->direction) { - aEvent.mnDelta = -pSEvent->delta_y * 120; - aEvent.mnNotchDelta = aEvent.mnDelta < 0 ? -1 : +1; - if (aEvent.mnDelta == 0) - aEvent.mnDelta = aEvent.mnNotchDelta; - aEvent.mbHorz = false; - aEvent.mnScrollLines = std::abs(aEvent.mnDelta) / 40; - if (aEvent.mnScrollLines == 0) - aEvent.mnScrollLines = 1; - - pThis->CallCallback(SALEVENT_WHEELMOUSE, &aEvent); + case GDK_SCROLL_SMOOTH: + // 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 + // by 120 where a single mouse wheel click is an incoming delta_x of 1 + // and divide that by 40 to get the number of scrollines + if (pEvent->delta_x != 0.0) + { + aEvent.mnDelta = -pEvent->delta_x * 120; + aEvent.mnNotchDelta = aEvent.mnDelta < 0 ? -1 : +1; + if (aEvent.mnDelta == 0) + aEvent.mnDelta = aEvent.mnNotchDelta; + aEvent.mbHorz = true; + aEvent.mnScrollLines = std::abs(aEvent.mnDelta) / 40; + if (aEvent.mnScrollLines == 0) + aEvent.mnScrollLines = 1; + + pThis->CallCallback(SALEVENT_WHEELMOUSE, &aEvent); + } + + if (pEvent->delta_y != 0.0) + { + aEvent.mnDelta = -pEvent->delta_y * 120; + aEvent.mnNotchDelta = aEvent.mnDelta < 0 ? -1 : +1; + if (aEvent.mnDelta == 0) + aEvent.mnDelta = aEvent.mnNotchDelta; + aEvent.mbHorz = false; + aEvent.mnScrollLines = std::abs(aEvent.mnDelta) / 40; + if (aEvent.mnScrollLines == 0) + aEvent.mnScrollLines = 1; + + pThis->CallCallback(SALEVENT_WHEELMOUSE, &aEvent); + } + + break; + + case GDK_SCROLL_UP: + aEvent.mnDelta = 120; + aEvent.mnNotchDelta = 1; + aEvent.mnScrollLines = 3; + aEvent.mbHorz = false; + pThis->CallCallback(SALEVENT_WHEELMOUSE, &aEvent); + break; + + case GDK_SCROLL_DOWN: + aEvent.mnDelta = -120; + aEvent.mnNotchDelta = -1; + aEvent.mnScrollLines = 3; + aEvent.mbHorz = false; + pThis->CallCallback(SALEVENT_WHEELMOUSE, &aEvent); + break; + + case GDK_SCROLL_LEFT: + aEvent.mnDelta = 120; + aEvent.mnNotchDelta = 1; + aEvent.mnScrollLines = 3; + aEvent.mbHorz = true; + pThis->CallCallback(SALEVENT_WHEELMOUSE, &aEvent); + break; + + case GDK_SCROLL_RIGHT: + aEvent.mnDelta = -120; + aEvent.mnNotchDelta = -1; + aEvent.mnScrollLines = 3; + aEvent.mbHorz = true; + pThis->CallCallback(SALEVENT_WHEELMOUSE, &aEvent); + break; } return true; -- cgit