I want to be able to tell if my application is currently in a "modal" state.
I know that if it is in this state using Cocoa's functions, I could tell by checking where [[NSApplication sharedApplication] modalWindow]
returns nil or not.
But it could also be in modal state using Carbon's functions (RunAppModalLoopForWindow
etc), and then Cocoa's modalWindow
does not tell us whether the application is modal.
Unfortunately, I don't have the choice to avoid Carbon as my app hosts old third party plugins which do use it.
Here's part of an example stack trace in a modal state due to carbon:
frame #12: 0x93ede739 CoreFoundation`__CFRunLoopRun + 1897
frame #13: 0x93eddd5a CoreFoundation`CFRunLoopRunSpecific + 394
frame #14: 0x93eddbbb CoreFoundation`CFRunLoopRunInMode + 123
frame #15: 0x930cee2d HIToolbox`RunCurrentEventLoopInMode + 259
frame #16: 0x930cebb2 HIToolbox`ReceiveNextEventCommon + 526
frame #17: 0x93119c4a HIToolbox`AcquireNextEventInMode + 75
frame #18: 0x93269aea HIToolbox`_AcquireNextEvent + 58
frame #19: 0x932585dc HIToolbox`_RunAppModalLoop + 168
frame #20: 0x932584ee HIToolbox`RunAppModalLoopForWindow + 130
I could trace the stack and see that _RunAppModalLoop
is there, but I don't like this solution.
This can be done by enumerating all the app's windows and checking if they are modal by using GetWindowModality
.
bool isAnyCarbonWindowModal()
{
for (
WindowRef win = GetFrontWindowOfClass(kAllWindowClasses, true);
win != nullptr;
win = GetNextWindowOfClass(win, kAllWindowClasses, true))
{
WindowModality modalKind;
WindowRef unavailableWindow;
GetWindowModality(win, &modalKind, &unavailableWindow);
if (kWindowModalityAppModal == modalKind)
return true;
}
return false;
}