If you create and install a child component over your mainComponent, and set it to be modal (so as to simulate a modal dialog for example), if you then minimize that state to the dock and restore it, the modal component is no longer modal.
Test Project:
ModalComponent.zip (11.4 KB)
Steps to reproduce:
-
In the MainWindow, click the “Modal Component” button. This installs the child component and calls
enterModalState()
. The modal component comes up resembling a dialog. Test modality by trying to activate any buttons in the background mainComponent. Cannot do so - it is modal. -
Click on the minimize button in the title bar to minimize it to the dock.
-
Restore it from the dock. Test modality - it is now gone and you can freely click buttons in the background mainComponent.
What happens is:
When the MainWindow is minimized, in ModalComponentManager::ModalItem
, the ComponentMovementWatcher
that is attached to each modal component receives a componentVisibilityChanged
:
void componentVisibilityChanged() override
{
if (! component->isShowing())
cancel();
}
This then causes the active flag for that component to be set to false, and an asyncUpdate is triggered:
void cancel()
{
if (isActive)
{
isActive = false;
if (auto* mcm = ModalComponentManager::getInstanceWithoutCreating())
mcm->triggerAsyncUpdate();
}
}
handleAsyncUpdate
then removes the component from the stack of modal components. Then when you unminimize, the component is no longer modal:
void ModalComponentManager::handleAsyncUpdate()
{
for (int i = stack.size(); --i >= 0;)
{
auto* item = stack.getUnchecked (i);
if (! item->isActive)
{
std::unique_ptr<ModalItem> deleter (stack.removeAndReturn (i));
Component::SafePointer<Component> compToDelete (item->autoDelete ? item->component : nullptr);
for (int j = item->callbacks.size(); --j >= 0;)
item->callbacks.getUnchecked (j)->modalStateFinished (item->returnValue);
compToDelete.deleteAndZero();
}
}
}
Tested with JUCE 7.0.5 and Mojave. I did not test on Windows but from the code, I expect similar behavior.