mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Component: Ensure that mouseEnter and mouseExit calls are balanced when entering/leaving modal state
This commit is contained in:
parent
b465f60851
commit
f85ede6b47
1 changed files with 28 additions and 8 deletions
|
|
@ -470,6 +470,24 @@ struct Component::ComponentHelpers
|
|||
for (auto* child : c.childComponentList)
|
||||
releaseAllCachedImageResources (*child);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
static bool modalWouldBlockComponent (const Component& maybeBlocked, Component* modal)
|
||||
{
|
||||
return modal != nullptr
|
||||
&& modal != &maybeBlocked
|
||||
&& ! modal->isParentOf (&maybeBlocked)
|
||||
&& ! modal->canModalEventBeSentToComponent (&maybeBlocked);
|
||||
}
|
||||
|
||||
template <typename Function>
|
||||
static void sendMouseEventToComponentsThatAreBlockedByModal (Component& modal, Function&& function)
|
||||
{
|
||||
for (auto& ms : Desktop::getInstance().getMouseSources())
|
||||
if (auto* c = ms.getComponentUnderMouse())
|
||||
if (modalWouldBlockComponent (*c, &modal))
|
||||
(c->*function) (ms, ms.getScreenPosition(), Time::getCurrentTime());
|
||||
}
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
|
|
@ -1720,6 +1738,11 @@ void Component::enterModalState (bool shouldTakeKeyboardFocus,
|
|||
|
||||
if (! isCurrentlyModal (false))
|
||||
{
|
||||
// While this component is in modal state it may block other components from receiving
|
||||
// mouseExit events. To keep mouseEnter and mouseExit calls balanced on these components,
|
||||
// we must manually force the mouse to "leave" blocked components.
|
||||
ComponentHelpers::sendMouseEventToComponentsThatAreBlockedByModal (*this, &Component::internalMouseExit);
|
||||
|
||||
auto& mcm = *ModalComponentManager::getInstance();
|
||||
mcm.startModal (this, deleteWhenDismissed);
|
||||
mcm.attachCallback (this, callback);
|
||||
|
|
@ -1746,10 +1769,10 @@ void Component::exitModalState (int returnValue)
|
|||
mcm.endModal (this, returnValue);
|
||||
mcm.bringModalComponentsToFront();
|
||||
|
||||
// If any of the mouse sources are over another Component when we exit the modal state then send a mouse enter event
|
||||
for (auto& ms : Desktop::getInstance().getMouseSources())
|
||||
if (auto* c = ms.getComponentUnderMouse())
|
||||
c->internalMouseEnter (ms, ms.getScreenPosition(), Time::getCurrentTime());
|
||||
// While this component is in modal state it may block other components from receiving
|
||||
// mouseEnter events. To keep mouseEnter and mouseExit calls balanced on these components,
|
||||
// we must manually force the mouse to "enter" blocked components.
|
||||
ComponentHelpers::sendMouseEventToComponentsThatAreBlockedByModal (*this, &Component::internalMouseEnter);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1772,10 +1795,7 @@ bool Component::isCurrentlyModal (bool onlyConsiderForemostModalComponent) const
|
|||
|
||||
bool Component::isCurrentlyBlockedByAnotherModalComponent() const
|
||||
{
|
||||
auto* mc = getCurrentlyModalComponent();
|
||||
|
||||
return ! (mc == nullptr || mc == this || mc->isParentOf (this)
|
||||
|| mc->canModalEventBeSentToComponent (this));
|
||||
return ComponentHelpers::modalWouldBlockComponent (*this, getCurrentlyModalComponent());
|
||||
}
|
||||
|
||||
int JUCE_CALLTYPE Component::getNumCurrentlyModalComponents() noexcept
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue