Search code examples
objective-cmacoscocoapluginsfirebreath

NPAPI plugin - Mac OS - [NSAlert runModal] does not work correctly on Firefox when multiple modal dialogs are opened


I am working on some plug-in and I need user interaction during plug-in loading. Precisely, when plug-in is being loaded pop-up modal dialog is shown and user must to allow (deny) the plug-in to have access to the external devices by clicking "Allow" or "Deny".

I use Firebreath's method FB::BrowserHost::ScheduleOnMainThread to schedule function call "showPopUpAlert" on main thread and for the modal dialog I use Cocoa API calls [alert runModal] and [alert abortModal] or [alert stopModal].

When I run plug-in in one tab, do not answer by clicking on the dialog's buttons (dialog is still open) and attempt to load the plug-in again in separate tab new instance of the dialog is shown on top. Then I can not access to the first opened dialog until the second one is active.

If I click on second opened dialog Allow or Deny it will be closed and the first one will be still active.

Problem raise when I attempt to close one of the two opened tabs.

1) If I close the second opened tab their pop-up dialog will be closed and the first opened dialog beneath will be still active. 2) I attempt to close first opened tab the second pop-up dialog will be closed and the first opened will be inactive.

That is only Firefox problem, Chrome and Safari work perfectly.

On Chrome and Safari if one dialog is active whole browser is blocked and it is not possible to open new tab until the dialog is opened.

It would be great if it is possible to make Firefox to work as Chrome and Safari. Do you have any suggestions?

I've tried to access to the browser window and to use method beginSheetModalForWindow but I've read on several topics that it is not possible because plug-in and browser are running in separate threads.

My code relies on the taxilian's example, please take a look and I would be very grateful if somebody could help me.

Regards, l3r

Sorry if I was unclear.

I have sample web app which use the plug-in.

When I run the sample app one modal dialog (NSAlert) is shown with a question: "Do you allow the plug-in to access to your external devices?" The question could be answered by clicking on "Allow" or "Deny" button.

1) I run sample app in Firefox in one tab and do not answer the question, the modal dialog stays on top.

2) I open one new tab and run the sample app again, new modal dialog is shown. Now two modal dialogs appear one in front of other.

3) If I close the tab opened in 1), the modal dialog from 2) will be closed, and the modal dialog from 1) will stay inactive (It is not possible to answer the question).

I would like to prevent browser (Firefox) from opening new tab if one modal dialog have previously been opened, or if I close one tab I would like their modal dialog to be closed not the other one which is on top. Is it possible? Do you have some suggestions?

I hope I have been a bit more clear.

Regards, l3r


Solution

  • Based on your updated text, it sounds like what you really are asking is how to prevent more than one tab from opening a modal dialog.

    Basically, what I would recommend is to create a global singleton that manages the dialog; put a YourAPIWeakPtr on it to reference what it should call back (or something similar) and then check if another dialog is open before allowing anything to open a second one.

    You could either then reject the old one and close the dialog or you could ignore future requests when a new request comes in and an old is still open.

    Remember that you're still in the same process for all instances of the plugin, so it's just a question of making sure that the resource can only be used once per process.