Open Bug 478073 Opened 11 years ago Updated 7 years ago
We need some changes to Gecko to get modal dialogs working properly on OS X
Gecko's implementation of modal dialogs currently doesn't work very well on OS X. This is largely because, up til now, we've tried to make Cocoa widgets' modal dialogs behave exactly as they do on Windows and Linux. But modal dialogs behave significantly differently in "native" Cocoa (or Carbon) apps than they do on Windows or Linux. We've implemented hacked (ersatz) modal windows in Cocoa widgets that behave more like those on Windows and Linux (see bug 395465). But these have never worked perfectly. And we've had to continue using native modal dialogs (like Print, Page Setup, Open File and Save As), which don't work at all well with Gecko code -- necessitating further hacks (see bug 436473, bug 442442, bug 468393 and bug 476541). This strategy is wrong-headed -- it requires code in Cocoa widgets that's over-complex and error-prone, and still doesn't work quite correctly. We need to acknowledge that modal windows don't work the same way on OS X as they do on Windows and Linux, and to allow Cocoa widgets' implementation of them to be different. We also need to make some changes to Gecko code to allow it to accomodate certain quirks of Cocoa modal dialogs (particularly of modal windows). In following comments I'll outline the differences between how modal dialogs behave on Windows and Linux (on the one hand) and OS X (on the other). I'll also describe (in a general way) the changes that are needed in Gecko code to make its modal dialogs work well on OS X. These changes won't be large, and won't require any modifications to how modal dialogs behave on other platforms (besides OS X).
I) Low-level Quirks in Standard OS X Modal Dialogs Above I mentioned several high-level (and user-visible) differences in how modal dialogs are implemented in Firefox on Windows and Linux, and how they're implemented in native apps on OS X. But there are also a couple of low-level (user-invisible) quirks to how modal dialogs are implemented on OS X (ones not found on Windows or Linux) that make it very difficult to use them in Gecko (as it's currently written): 1) Native app-modal dialogs run their own (nested) event loops. But Gecko (in nsXULWindow::ShowModal()) insists on running its own (nested) event loop for the modal dialogs that it spawns. This is fine for sheets (which don't run their own event loops). But it makes it impossible to run a native app-modal dialog from nsXULWindow::ShowModal() (as it's now written). 2) OS X provides a number of canned modal dialogs for common tasks (like Open File, Save As, Print and Page Setup). These are used by all standard apps -- which means that (practically speaking) they're not optional. And in fact Firefox currently uses them. But none of these is displayed via nsPromptService::Alert() (and friends) or nsGlobalWindow::Alert() (and friends). So there's currently no way for Gecko to tell that one of these dialogs is being displayed (for example by calling nsGlobalWindow::IsInModalState()). And so Gecko doesn't have the option (in nsGlobalWindow::SetTimeoutOrInterval() and nsGlobalWindow::RunTimeout()) to postpone showing (i.e. nesting) another modal dialog while one of these canned modal dialogs is open. II) Changes Needed to Accomodate These Quirks 1) nsXULWindow::ShowModal() should be able to "delegate" the running of its nested event loop. In other words, there should be the option to have nsXULWindow::ShowModal() call a callback, which runs a "native" (or semi-native) event loop. This callback would be responsible for processing both Gecko events (using NS_ProcessNextEvent()) and native events. The callback could (as nsXULWindow::ShowModal()) now does) break out of the event loop (and return) when NS_ProcessNextEvent() returns FALSE. 2) There should be some way to notify Gecko that a native modal dialog is running that it didn't spawn in the usual way (i.e. using nsGlobalWindow::Alert() and friends). There should probably also be some way to tell Gecko what kind of modal dialog is running -- either a window-modal dialog running above a given parent window or an app-modal dialog running above all other windows.
> So we should either go back to using a sheet for showModalDialog(), or accept > that it will be app-modal. The problem is that option 1 is not really very web-compatible, while option 2 is just terrible UI... I just checked, and Safari seems to make it app-modal, so I suppose that's the way to go. Might still not be quite web-compatible, but if that's the case we'll find out.
You need to log in before you can comment on or make changes to this bug.