crashreport: 644837b5-c445-4779-a75d-dd69fc2e3a6f

drop hint of previous window to get mouse wheel event
when that window is disposed in order to drop any
references to it immediately that happens to avoid
anything else lingering too late

move the VclPtr into ImplSVData alongside the rest of the things like this so
we can remove the static VclPtr which itself replaced a relatively harmless
static Window*

(cherry picked from commit bdfccfde308f0267965933a8273e6e9201a2c67c)
(cherry picked from commit 35205c6e3e2f85d9b7db935689ec949c98e7e431)

Change-Id: I1e172071b711b6e4ded9a813ee3de730d3dfdf38
Reviewed-on: https://gerrit.libreoffice.org/26337
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Michael Stahl <mstahl@redhat.com>
diff --git a/vcl/inc/svdata.hxx b/vcl/inc/svdata.hxx
index eef919d..6522da1a 100644
--- a/vcl/inc/svdata.hxx
+++ b/vcl/inc/svdata.hxx
@@ -208,6 +208,7 @@ struct ImplSVWinData
    AutoTimer*              mpTrackTimer;                   // tracking timer
    ImageList*              mpMsgBoxImgList;                // ImageList for MessageBox
    VclPtr<vcl::Window>     mpAutoScrollWin;                // window, that is in AutoScrollMode mode
    VclPtr<vcl::Window>     mpLastWheelWindow;              // window, that last received a mouse wheel event
    StartTrackingFlags      mnTrackFlags;                   // tracking flags
    StartAutoScrollFlags    mnAutoScrollFlags;              // auto scroll flags
    bool                    mbNoDeactivate;                 // true: do not execute Deactivate
diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx
index bd2a662..2c4164e 100644
--- a/vcl/source/window/window.cxx
+++ b/vcl/source/window/window.cxx
@@ -481,6 +481,10 @@ void Window::dispose()
    if( pSVData->maWinData.mpActiveApplicationFrame == this )
        pSVData->maWinData.mpActiveApplicationFrame = nullptr;

    // reset hint of what was the last wheeled window
    if( pSVData->maWinData.mpLastWheelWindow == this )
        pSVData->maWinData.mpLastWheelWindow = nullptr;

    // reset marked windows
    if ( mpWindowImpl->mpFrameData != nullptr )
    {
diff --git a/vcl/source/window/winproc.cxx b/vcl/source/window/winproc.cxx
index 66e89448..fce0d79 100644
--- a/vcl/source/window/winproc.cxx
+++ b/vcl/source/window/winproc.cxx
@@ -1509,26 +1509,27 @@ public:
bool HandleWheelEvent::HandleEvent(const SalWheelMouseEvent& rEvt)
{
    static SalWheelMouseEvent aPreviousEvent;
    static VclPtr<vcl::Window> xPreviousWindow;

    if (!Setup())
        return false;

    VclPtr<vcl::Window> xMouseWindow = FindTarget();

    ImplSVData* pSVData = ImplGetSVData();

    // avoid the problem that scrolling via wheel to this point brings a widget
    // under the mouse that also accepts wheel commands, so stick with the old
    // widget if the time gap is very small
    if (shouldReusePreviousMouseWindow(aPreviousEvent, rEvt) && acceptableWheelScrollTarget(xPreviousWindow))
    if (shouldReusePreviousMouseWindow(aPreviousEvent, rEvt) && acceptableWheelScrollTarget(pSVData->maWinData.mpLastWheelWindow))
    {
        xMouseWindow = xPreviousWindow.get();
        xMouseWindow = pSVData->maWinData.mpLastWheelWindow;
    }

    aPreviousEvent = rEvt;

    xPreviousWindow = Dispatch(xMouseWindow);
    pSVData->maWinData.mpLastWheelWindow = Dispatch(xMouseWindow);

    return xPreviousWindow;
    return pSVData->maWinData.mpLastWheelWindow.get();
}

class HandleGestureEvent : public HandleGestureEventBase