Some notes on this bug. It’s a problem with Component or Button. It’s not a repaint issue. The internal state of Button is stuck in mouseOver. After clicking on the button no mouseExit event is ever sent to the Button even once the mouse has moved away from the popup menu.
The problem is fixed by moving updateState to be after the click event is triggered. And copying the “deletionWatcher” pattern from elsewhere in Button.
Suggested replacement code is below and would fix another long standing niggle
Using setTriggeredOnMouseDown(…) doesn’t have the same problem with PopupMenu, the mouseOver state clears for different reasons. Although i wonder if it would be more consistent to make the same change to the mouseDown(…) call.
I think we’d still want to keep the first updateState() call as moving it might cause some subtle bugs due to the ordering of the state change message and internal click callback changing. updateState() will only send a change message if the state has actually changed so we don’t need to worry about duplicate messages, so something like this should work whilst maintaining the old order:
void Button::mouseUp (const MouseEvent& e)
{
const auto wasDown = isDown();
const auto wasOver = isOver();
updateState (isMouseSourceOver (e), false);
if (wasDown && wasOver && ! triggerOnMouseDown)
{
if (lastStatePainted != buttonDown)
flashButtonState();
WeakReference<Component> deletionWatcher (this);
internalClickCallback (e.mods);
if (deletionWatcher != nullptr)
updateState (isMouseSourceOver (e), false);
}
}
I don’t think a similar change is needed in mouseDown() since we always call updateState (true, true); so the second call after the click callback would be redundant.
I’m pretty confident that’ll fix it. As long as that second post-event updateState is triggered. This will be a great fix. Sticky highlights with PopupMenus have been a low level niggle of a problem for years with loads of JUCE projects