vcl/inc/window.h | 2 ++ vcl/source/window/window.cxx | 2 ++ vcl/source/window/window2.cxx | 37 ++++++++++++++++++++++--------------- 3 files changed, 26 insertions(+), 15 deletions(-)
New commits: commit fe21365c5a9083ae1f086ea48614263b3a75ab3e Author: Jonas Eyov <je...@proton.me> AuthorDate: Fri Nov 18 03:40:57 2022 +0000 Commit: Caolán McNamara <caol...@redhat.com> CommitDate: Mon Nov 21 17:28:45 2022 +0100 tdf#143209 vcl: track partial scroll deltas this makes scrolling in calc smoother and makes left/up scrolling the same speed as right/down scrolling, which was previously not the case. prior to this change, Window::HandleScrollCommand only checked each event for being a large enough scroll to advance one unit. this happened in lcl_HandleScrollHelper by way of o3tl::saturating_cast, which meant that nonzero upward/leftward scrolls were always worth at least one unit, while downward/rightward scrolls needed to be larger than 1 to count. now, we accumulate partial scroll offsets in WindowImpl and perform a saturating cast on the absolute value, so behavior is symmetric and sensitive to accumulated small scroll values. this feels smoother and is more correct. Change-Id: Id3692d14edd45ed26f2952e3418e4d82806e1fc4 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/142948 Tested-by: Jenkins Tested-by: Caolán McNamara <caol...@redhat.com> Reviewed-by: Caolán McNamara <caol...@redhat.com> diff --git a/vcl/inc/window.h b/vcl/inc/window.h index 639bee80e82c..6f10445abf39 100644 --- a/vcl/inc/window.h +++ b/vcl/inc/window.h @@ -256,6 +256,8 @@ public: vcl::Cursor* mpCursor; PointerStyle maPointer; Fraction maZoom; + double mfPartialScrollX; + double mfPartialScrollY; OUString maText; std::optional<vcl::Font> mpControlFont; diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx index 4705fe516ce5..5cfc50d717c0 100644 --- a/vcl/source/window/window.cxx +++ b/vcl/source/window/window.cxx @@ -590,6 +590,8 @@ WindowImpl::WindowImpl( vcl::Window& rWindow, WindowType nType ) { mxOutDev = VclPtr<vcl::WindowOutputDevice>::Create(rWindow); maZoom = Fraction( 1, 1 ); + mfPartialScrollX = 0.0; + mfPartialScrollY = 0.0; maWinRegion = vcl::Region(true); maWinClipRegion = vcl::Region(true); mpWinData = nullptr; // Extra Window Data, that we don't need for all windows diff --git a/vcl/source/window/window2.cxx b/vcl/source/window/window2.cxx index b6c4ee25415a..978dc0b6ecf8 100644 --- a/vcl/source/window/window2.cxx +++ b/vcl/source/window/window2.cxx @@ -598,12 +598,14 @@ tools::Long Window::GetDrawPixel( OutputDevice const * pDev, tools::Long nPixels return nP; } -static void lcl_HandleScrollHelper( Scrollable* pScrl, double nN, bool isMultiplyByLineSize ) +// returns how much was actually scrolled (so that abs(retval) <= abs(nN)) +static double lcl_HandleScrollHelper( Scrollable* pScrl, double nN, bool isMultiplyByLineSize ) { if (!pScrl || !nN || pScrl->Inactive()) - return; + return 0.0; tools::Long nNewPos = pScrl->GetThumbPos(); + double scrolled = nN; if ( nN == double(-LONG_MAX) ) nNewPos += pScrl->GetPageSize(); @@ -616,13 +618,22 @@ static void lcl_HandleScrollHelper( Scrollable* pScrl, double nN, bool isMultipl nN*=pScrl->GetLineSize(); } - const double fVal = nNewPos - nN; + // compute how many quantized units to scroll + tools::Long magnitude = o3tl::saturating_cast<tools::Long>(abs(nN)); + tools::Long change = copysign(magnitude, nN); + + nNewPos = nNewPos - change; - nNewPos = o3tl::saturating_cast<tools::Long>(fVal); + scrolled = double(change); + // convert back to chunked/continuous + if(isMultiplyByLineSize){ + scrolled /= pScrl->GetLineSize(); + } } pScrl->DoScroll( nNewPos ); + return scrolled; } bool Window::HandleScrollCommand( const CommandEvent& rCmd, @@ -668,6 +679,9 @@ bool Window::HandleScrollCommand( const CommandEvent& rCmd, { double nScrollLines = pData->GetScrollLines(); double nLines; + double* partialScroll = pData->IsHorz() + ? &mpWindowImpl->mfPartialScrollX + : &mpWindowImpl->mfPartialScrollY; if ( nScrollLines == COMMAND_WHEEL_PAGESCROLL ) { if ( pData->GetDelta() < 0 ) @@ -676,13 +690,12 @@ bool Window::HandleScrollCommand( const CommandEvent& rCmd, nLines = double(LONG_MAX); } else - nLines = pData->GetNotchDelta() * nScrollLines; + nLines = *partialScroll + pData->GetNotchDelta() * nScrollLines; if ( nLines ) { - ImplHandleScroll( nullptr, - 0L, - pData->IsHorz() ? pHScrl : pVScrl, - nLines ); + Scrollable* pScrl = pData->IsHorz() ? pHScrl : pVScrl; + double scrolled = lcl_HandleScrollHelper( pScrl, nLines, true ); + *partialScroll = nLines - scrolled; bRet = true; } } @@ -806,12 +819,6 @@ bool Window::HandleScrollCommand( const CommandEvent& rCmd, return bRet; } -// Note that when called for CommandEventId::Wheel above, despite its name, -// pVScrl isn't necessarily the vertical scroll bar. Depending on -// whether the scroll is horizontal or vertical, it is either the -// horizontal or vertical scroll bar. nY is correspondingly either -// the horizontal or vertical scroll amount. - void Window::ImplHandleScroll( Scrollable* pHScrl, double nX, Scrollable* pVScrl, double nY ) {