diff options
author | Caolán McNamara <caolanm@redhat.com> | 2017-05-18 15:05:27 +0100 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2017-05-18 16:24:11 +0200 |
commit | 7f60978b2ccd0e17816b78bde60c6e0e60a9d52e (patch) | |
tree | feb12ebdf4c2bfd15f08ec170ee18a099e8eb21a /vcl/unx | |
parent | 5206b0376dcd511843f0e6cb072fe4184adcc487 (diff) |
Related: rhbz#1367846 queue and merge scroll events
Change-Id: Ib45f61bbb35bd240829491ac8a79803222974778
Reviewed-on: https://gerrit.libreoffice.org/37779
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'vcl/unx')
-rw-r--r-- | vcl/unx/gtk/gtksalframe.cxx | 15 | ||||
-rw-r--r-- | vcl/unx/gtk3/gtk3gtkframe.cxx | 131 |
2 files changed, 104 insertions, 42 deletions
diff --git a/vcl/unx/gtk/gtksalframe.cxx b/vcl/unx/gtk/gtksalframe.cxx index 02e06ae8c053..f32e49ad4f7b 100644 --- a/vcl/unx/gtk/gtksalframe.cxx +++ b/vcl/unx/gtk/gtksalframe.cxx @@ -2782,8 +2782,9 @@ gboolean GtkSalFrame::signalButton( GtkWidget*, GdkEventButton* pEvent, gpointer return true; } -gboolean GtkSalFrame::signalScroll( GtkWidget*, GdkEventScroll* pEvent, gpointer frame ) +gboolean GtkSalFrame::signalScroll(GtkWidget*, GdkEvent* pInEvent, gpointer frame) { + GdkEventScroll& rEvent = pInEvent->scroll; GtkSalFrame* pThis = static_cast<GtkSalFrame*>(frame); static sal_uLong nLines = 0; @@ -2795,16 +2796,16 @@ gboolean GtkSalFrame::signalScroll( GtkWidget*, GdkEventScroll* pEvent, gpointer nLines = SAL_WHEELMOUSE_EVENT_PAGESCROLL; } - bool bNeg = (pEvent->direction == GDK_SCROLL_DOWN || pEvent->direction == GDK_SCROLL_RIGHT ); + bool bNeg = (rEvent.direction == GDK_SCROLL_DOWN || rEvent.direction == GDK_SCROLL_RIGHT ); SalWheelMouseEvent aEvent; - aEvent.mnTime = pEvent->time; - aEvent.mnX = (sal_uLong)pEvent->x; - aEvent.mnY = (sal_uLong)pEvent->y; + aEvent.mnTime = rEvent.time; + aEvent.mnX = (sal_uLong)rEvent.x; + aEvent.mnY = (sal_uLong)rEvent.y; aEvent.mnDelta = bNeg ? -120 : 120; aEvent.mnNotchDelta = bNeg ? -1 : 1; aEvent.mnScrollLines = nLines; - aEvent.mnCode = GetMouseModCode( pEvent->state ); - aEvent.mbHorz = (pEvent->direction == GDK_SCROLL_LEFT || pEvent->direction == GDK_SCROLL_RIGHT); + aEvent.mnCode = GetMouseModCode( rEvent.state ); + aEvent.mbHorz = (rEvent.direction == GDK_SCROLL_LEFT || rEvent.direction == GDK_SCROLL_RIGHT); if( AllSettings::GetLayoutRTL() ) aEvent.mnX = pThis->maGeometry.nWidth-1-aEvent.mnX; diff --git a/vcl/unx/gtk3/gtk3gtkframe.cxx b/vcl/unx/gtk3/gtk3gtkframe.cxx index bc19821cbdf5..30a729c5cbcc 100644 --- a/vcl/unx/gtk3/gtk3gtkframe.cxx +++ b/vcl/unx/gtk3/gtk3gtkframe.cxx @@ -807,6 +807,9 @@ void GtkSalFrame::InvalidateGraphics() GtkSalFrame::~GtkSalFrame() { + m_aSmoothScrollIdle.Stop(); + m_aSmoothScrollIdle.ClearInvokeHandler(); + if (m_pDropTarget) { m_pDropTarget->deinitialize(); @@ -992,6 +995,8 @@ void GtkSalFrame::InitCommon() m_aDamageHandler.handle = this; m_aDamageHandler.damaged = ::damaged; + m_aSmoothScrollIdle.SetInvokeHandler(LINK(this, GtkSalFrame, AsyncScroll)); + m_pTopLevelGrid = GTK_GRID(gtk_grid_new()); gtk_container_add(GTK_CONTAINER(m_pWindow), GTK_WIDGET(m_pTopLevelGrid)); @@ -2653,53 +2658,107 @@ gboolean GtkSalFrame::signalButton( GtkWidget*, GdkEventButton* pEvent, gpointer return true; } -gboolean GtkSalFrame::signalScroll(GtkWidget*, GdkEventScroll* pEvent, gpointer frame) +void GtkSalFrame::LaunchAsyncScroll(GdkEvent* pEvent) { - UpdateLastInputEventTime(pEvent->time); + //if we don't match previous pending states, flush that queue now + if (!m_aPendingScrollEvents.empty() && pEvent->scroll.state != m_aPendingScrollEvents.back()->scroll.state) + { + m_aSmoothScrollIdle.Stop(); + m_aSmoothScrollIdle.Invoke(); + assert(m_aPendingScrollEvents.empty()); + } + //add scroll event to queue + m_aPendingScrollEvents.push_back(gdk_event_copy(pEvent)); + if (!m_aSmoothScrollIdle.IsActive()) + m_aSmoothScrollIdle.Start(); +} - GtkSalFrame* pThis = static_cast<GtkSalFrame*>(frame); +IMPL_LINK_NOARG(GtkSalFrame, AsyncScroll, Timer *, void) +{ + assert(!m_aPendingScrollEvents.empty()); SalWheelMouseEvent aEvent; - aEvent.mnTime = pEvent->time; - aEvent.mnX = (sal_uLong)pEvent->x; + GdkEvent* pEvent = m_aPendingScrollEvents.back(); + aEvent.mnTime = pEvent->scroll.time; + aEvent.mnX = (sal_uLong)pEvent->scroll.x; + // --- RTL --- (mirror mouse pos) if (AllSettings::GetLayoutRTL()) - aEvent.mnX = pThis->maGeometry.nWidth - 1 - aEvent.mnX; - aEvent.mnY = (sal_uLong)pEvent->y; - aEvent.mnCode = GetMouseModCode( pEvent->state ); + aEvent.mnX = maGeometry.nWidth - 1 - aEvent.mnX; + aEvent.mnY = (sal_uLong)pEvent->scroll.y; + aEvent.mnCode = GetMouseModCode( pEvent->scroll.state ); - switch (pEvent->direction) + double delta_x(0.0), delta_y(0.0); + for (auto pSubEvent : m_aPendingScrollEvents) { - 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 scroll lines - 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.0; - pThis->CallCallbackExc(SalEvent::WheelMouse, &aEvent); - } + delta_x += pSubEvent->scroll.delta_x; + delta_y += pSubEvent->scroll.delta_y; + gdk_event_free(pSubEvent); + } + m_aPendingScrollEvents.clear(); - 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.0; - pThis->CallCallbackExc(SalEvent::WheelMouse, &aEvent); - } + // 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 scroll lines + if (delta_x != 0.0) + { + aEvent.mnDelta = -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.0; + CallCallbackExc(SalEvent::WheelMouse, &aEvent); + } - break; + if (delta_y != 0.0) + { + aEvent.mnDelta = -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.0; + CallCallbackExc(SalEvent::WheelMouse, &aEvent); + } +} +gboolean GtkSalFrame::signalScroll(GtkWidget*, GdkEvent* pInEvent, gpointer frame) +{ + GdkEventScroll& rEvent = pInEvent->scroll; + + UpdateLastInputEventTime(rEvent.time); + + GtkSalFrame* pThis = static_cast<GtkSalFrame*>(frame); + + if (rEvent.direction == GDK_SCROLL_SMOOTH) + { + pThis->LaunchAsyncScroll(pInEvent); + return true; + } + + //if we have smooth scrolling previous pending states, flush that queue now + if (!pThis->m_aPendingScrollEvents.empty()) + { + pThis->m_aSmoothScrollIdle.Stop(); + pThis->m_aSmoothScrollIdle.Invoke(); + assert(pThis->m_aPendingScrollEvents.empty()); + } + + SalWheelMouseEvent aEvent; + + aEvent.mnTime = rEvent.time; + aEvent.mnX = (sal_uLong)rEvent.x; + // --- RTL --- (mirror mouse pos) + if (AllSettings::GetLayoutRTL()) + aEvent.mnX = pThis->maGeometry.nWidth - 1 - aEvent.mnX; + aEvent.mnY = (sal_uLong)rEvent.y; + aEvent.mnCode = GetMouseModCode(rEvent.state); + + switch (rEvent.direction) + { case GDK_SCROLL_UP: aEvent.mnDelta = 120; aEvent.mnNotchDelta = 1; @@ -2731,6 +2790,8 @@ gboolean GtkSalFrame::signalScroll(GtkWidget*, GdkEventScroll* pEvent, gpointer aEvent.mbHorz = true; pThis->CallCallbackExc(SalEvent::WheelMouse, &aEvent); break; + default: + break; } return true; |