From 847513d409b146400515d7796d196b8b2a142036 Mon Sep 17 00:00:00 2001 From: Luboš Luňák Date: Mon, 2 Feb 2015 16:38:18 +0100 Subject: compress (X11) mouse wheel events There is one event per wheel step, so wheeling more can create a number of wheel events, and LO processed those one by one. If processing one took long (e.g. the repaint was complicated), the scrolling visibly lagged. This commit works only for X11 VCL backend (and by extension, KDE3/4 backends). Change-Id: I5eff7446da16167ec75925e75243314c68bc81a4 --- vcl/unx/generic/window/salframe.cxx | 59 +++++++++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 2 deletions(-) diff --git a/vcl/unx/generic/window/salframe.cxx b/vcl/unx/generic/window/salframe.cxx index a018b5bde8d9..9dee67235dd5 100644 --- a/vcl/unx/generic/window/salframe.cxx +++ b/vcl/unx/generic/window/salframe.cxx @@ -2718,6 +2718,51 @@ void X11SalFrame::SimulateKeyPress( sal_uInt16 nKeyCode ) vcl_sal::getSalDisplay(GetGenericData())->SimulateKeyPress(nKeyCode); } +namespace +{ +struct CompressWheelEventsData +{ + XEvent* firstEvent; + bool ignore; + int count; // number of compressed events +}; + +static Bool compressWheelEvents( Display*, XEvent* event, XPointer p ) +{ + CompressWheelEventsData* data = reinterpret_cast< CompressWheelEventsData* >( p ); + if( data->ignore ) + return False; // we're already after the events to compress + if( event->type == ButtonPress || event->type == ButtonRelease ) + { + const unsigned int mask = Button1Mask << ( event->xbutton.button - Button1 ); + if( event->xbutton.button == data->firstEvent->xbutton.button + && event->xbutton.window == data->firstEvent->xbutton.window + && event->xbutton.x == data->firstEvent->xbutton.x + && event->xbutton.y == data->firstEvent->xbutton.y + && ( event->xbutton.state | mask ) == ( data->firstEvent->xbutton.state | mask )) + { + // Count if it's another press (i.e. wheel start event). + if( event->type == ButtonPress ) + ++data->count; + return True; // And remove the event from the queue. + } + } + // Non-matching event, skip certain events that cannot possibly affect input processing, + // but otherwise ignore all further events. + switch( event->type ) + { + case Expose: + case NoExpose: + break; + default: + data->ignore = true; + break; + } + return False; +} + +} // namespace + long X11SalFrame::HandleMouseEvent( XEvent *pEvent ) { SalMouseEvent aMouseEvt = {0, 0, 0, 0, 0}; @@ -2936,13 +2981,23 @@ long X11SalFrame::HandleMouseEvent( XEvent *pEvent ) nLines = SAL_WHEELMOUSE_EVENT_PAGESCROLL; } + // Compress consecutive wheel events (way too fine scrolling may cause lags if one scrolling steps takes long). + CompressWheelEventsData data; + data.firstEvent = pEvent; + data.count = 1; + XEvent dummy; + do + { + data.ignore = false; + } while( XCheckIfEvent( pEvent->xany.display, &dummy, compressWheelEvents, reinterpret_cast< XPointer >( &data ))); + SalWheelMouseEvent aWheelEvt; aWheelEvt.mnTime = pEvent->xbutton.time; aWheelEvt.mnX = pEvent->xbutton.x; aWheelEvt.mnY = pEvent->xbutton.y; - aWheelEvt.mnDelta = bIncrement ? 120 : -120; + aWheelEvt.mnDelta = ( bIncrement ? 120 : -120 ) * data.count; aWheelEvt.mnNotchDelta = bIncrement ? 1 : -1; - aWheelEvt.mnScrollLines = nLines; + aWheelEvt.mnScrollLines = nLines * data.count; aWheelEvt.mnCode = sal_GetCode( pEvent->xbutton.state ); aWheelEvt.mbHorz = bHoriz; -- cgit v1.2.3