当打开多个模态对话框时,NPAPI插件 - Mac OS - [NSAlert runModal]在Firefox上无法正常工作

时间:2014-08-31 01:48:45

标签: objective-c macos cocoa plugins firebreath

我正在处理一些插件,我需要在插件加载期间进行用户交互。确切地说,当加载插件时,会显示弹出模式对话框,用户必须通过单击“允许”或“拒绝”允许(拒绝)插件访问外部设备。

我使用Firebreath的方法FB :: BrowserHost :: ScheduleOnMainThread来调度主线程上的函数调用“showPopUpAlert”,对于模态对话框,我使用Cocoa API调用[alert runModal]和[alert abortModal]或[alert stopModal]。 / p>

当我在一个选项卡中运行插件时,不要通过单击对话框的按钮(对话框仍然打开)来回答,并尝试在单独的选项卡中再次加载插件,对话框的新实例显示在顶部。然后我无法访问第一个打开的对话框,直到第二个对话框处于活动状态。

如果我点击第二个打开的对话框允许或拒绝它将被关闭,第一个将仍然有效。

当我尝试关闭两个打开的标签中的一个时出现问题。

1)如果我关闭第二个打开的选项卡,它们的弹出对话框将关闭,下面第一个打开的对话框仍然有效。  2)我尝试关闭第一个打开的选项卡,第二个弹出对话框将关闭,第一个打开的对话框将处于非活动状态。

这只是Firefox问题,Chrome和Safari工作正常。

在Chrome和Safari上,如果有一个对话框处于活动状态,则整个浏览器都会被阻止,并且在打开对话框之前无法打开新选项卡。

如果可以让Firefox作为Chrome和Safari工作,那就太棒了。你有什么建议吗?

我试图访问浏览器窗口并使用方法beginSheetModalForWindow,但我读过几个不可能的主题,因为插件和浏览器在不同的线程中运行。

我的代码依赖于taxilian's example,请看一下,如果有人可以帮助我,我将非常感激。

此致 L3R

很抱歉,如果我不清楚的话。

我有使用该插件的示例网络应用。

当我运行示例应用程序时,会显示一个模态对话框(NSAlert),其中包含一个问题:“您是否允许插件访问外部设备?” 可以通过单击“允许”或“拒绝”按钮来回答问题。

1)我在一个标签页面中运行Firefox中的示例应用程序并且没有回答问题,模态对话框保持在最顶层。

2)我打开一个新选项卡并再次运行示例应用程序,显示新的模态对话框。现在,两个模态对话框出现在另一个模式对话框前面。

3)如果我关闭1)中打开的标签,2)的模态对话框将关闭,1)的模态对话框将保持不活动状态(无法回答问题)。

我想阻止浏览器(Firefox)打开新选项卡,如果之前已打开过一个模式对话框,或者如果我关闭一个选项卡,我希望关闭模式对话框,而不是关闭顶部的另一个。 可能吗?你有什么建议吗?

我希望自己有点清楚。

此致 l3r

2 个答案:

答案 0 :(得分:1)

实际上,对话框不可能是NPAPI插件的真正模态;现代浏览器在一个单独的进程(而不是线程)中运行插件,而OS X没有办法在应用程序之间进行模式对话。相反,每个浏览器都会近似行为。

您可以针对Firefox提交错误,也许他们可以采用不同的方式处理这种情况,但从根本上说设计存在缺陷:强烈建议不要使用插件中的模态对话框,并且无法保证它能正常工作。

更好的解决方案是根本不使用模态对话框,并在插件的边界内放置所需的UI,因为打算使用NPAPI插件。

答案 1 :(得分:0)

根据您更新的文字,听起来您真正想知道的是如何防止多个标签打开模态对话框。

基本上,我建议创建一个管理对话框的全局单例;在其上放置一个YourAPIWeakPtr以引用它应该回调的内容(或类似内容),然后在允许任何东西打开第二个对话框之前检查另一个对话框是否打开。

您可以拒绝旧的并关闭对话框,也可以在新请求进入且旧的仍处于打开状态时忽略将来的请求。

请记住,对于插件的所有实例,您仍然处于相同的过程中,因此这只是确保每个进程只能使用一次资源的问题。