onMouseMoved issue for CViewContainers

If a view is inside a CViewContainer, onMouseMoved is reporting the mouse position (where) relative to the frame and not to the CViewContainer. onMouseEnter, and onMouseDown are working as expected . I spent a couple of hours trying to find the location of the bug to no avail.

UPDATE:
I suspect this bug was introduced here:

This attempt to get the view will only succeed if the mouse is pressed ! The result is that ‘where’ in onMouseMoved will be the frame position when the mouse isn’t down, and local when it is down.

Here is a not well tested fix.

void CViewContainer::onMouseMoveEvent (MouseMoveEvent& event)
{
	auto buttonState = buttonStateFromMouseEvent (event);
	auto mouseResult = onMouseMoved (event.mousePosition, buttonState);
	if (!(mouseResult == kMouseEventNotHandled || mouseResult == kMouseEventNotImplemented))
	{
		event.consumed = true;
		if (mouseResult == kMouseMoveEventHandledButDontNeedMoreEvents)
			event.ignoreFollowUpMoveAndUpEvents (true);
		return;
	}

    if (auto view = shared (getMouseDownView ()))
    {
        auto f = finally ([&, pos = event.mousePosition] () { event.mousePosition = pos; });
        event.mousePosition.offset (-getViewSize ().left, -getViewSize ().top);
        getTransform ().inverse ().transform (event.mousePosition);
        #if VSTGUI_ENABLE_DEPRECATED_METHODS
        mouseResult = view->callMouseListener (MouseListenerCall::MouseMoved, event.mousePosition,
                                               buttonState);
        if (!(mouseResult == kMouseEventNotHandled || mouseResult == kMouseEventNotImplemented))
        {
            event.consumed = true;
            if (mouseResult == kMouseMoveEventHandledButDontNeedMoreEvents)
                event.ignoreFollowUpMoveAndUpEvents (true);
            return;
        }
        #endif
        view->dispatchEvent (event);
    }

    else {
        auto f = finally ([&, pos = event.mousePosition] () { event.mousePosition = pos; });
        event.mousePosition.offset (-getViewSize ().left, -getViewSize ().top);
        getTransform ().inverse ().transform (event.mousePosition);

        for (auto it = pImpl->children.rbegin (), end = pImpl->children.rend (); it != end; ++it)
        {
            const auto& pV = *it;

            if (pV && pV->isVisible () && pV->getMouseEnabled () && pV->hitTest (event.mousePosition, event)) {
                #if VSTGUI_ENABLE_DEPRECATED_METHODS
                mouseResult = pV->callMouseListener (MouseListenerCall::MouseMoved, event.mousePosition, buttonState);

                if (!(mouseResult == kMouseEventNotHandled || mouseResult == kMouseEventNotImplemented))
                {
                    event.consumed = true;
                    if (mouseResult == kMouseMoveEventHandledButDontNeedMoreEvents)
                        event.ignoreFollowUpMoveAndUpEvents (true);
                    return;
                }
                #endif
                pV->dispatchEvent (event);
            }
        }
    }
}

I can confirm that I’m seeing similar weird where mouse positions when using onMouseMoved in 4.11. The position seems to switch back and forth between local and frame reference. The mouse click event position is stable and consistent.

Thanks for reporting this issue. I just pushed a fix for this on the develop branch on GitHub.

1 Like

Thanks @Arne_Scheffler , I updated my VSTGUI submodule to the develop branch and can confirm that the mouse position passed to my onMouseMoved is now local and everything works as expected. Thanks for the quick fix and the regression tests!

1 Like