【问题标题】:Safari 5.1 npapi issueSafari 5.1 npapi issue
【发布时间】:2011-08-17 13:33:40
【问题描述】:

几天以来,我一直在尝试解决以下问题,阅读了我在网上找到的所有关于 Mac 上的 npapi 的信息。

我们的目标是拥有一个适用于 safari 和 firefox(mac) 的 npapi 插件。 我的软件(我不能为此专门重写大约 45000 行 C 代码)基于附加到 NSDocument 的 NSView....

我有一个基于 webkit 版本的插件,我必须丢弃(感谢 Apple!)基于相同的 NSView。

我有一个在 firefox 上运行良好的 npapi 版本插件。在这个 npapi 插件中,我使用了 carbon window ref,基于它制作了一个 NSWindow: NSWindow *browserWindow = [[[NSWindow alloc] initWithWindowRef:wind]autorelease];

然后我把我的 NSView 放在这个窗口上就可以了。

现在问题是我不能在 safari 上做同样的事情。

看附图,窗口不在safari的窗口中!

我尝试了几种方法......它不起作用。 可可的咕噜能说我哪里做错了吗?还是这是一个已知问题?

NPError NPP_SetWindow(NPP 实例, NPWindow* 窗口){

NP_CGContext *ctx = 窗口->窗口; void *wind = ctx->window;

... 在 NSView 初始化函数中:

NSWindow *browserWindow = [[NSWindow alloc] initWithWindowRef:wind];
self = [super initWithFrame:frame];
if( self )
{
    [browserWindow makeFirstResponder: self];
    [self  setNextResponder: nil];
    [browserWindow setContentView:self];
    [self webPlugInInitialize];// my own initializing
}
return self;

【问题讨论】:

  • 我认为你不能在 firefox 上使用 NSView

标签: cocoa safari npapi


【解决方案1】:

在 Safari 5.1 中,网页渲染不是由 Safari 自己完成,而是在不同的进程上完成以增强安全性。打开活动监视器,您会看到名为“Safari Web 进程”或类似名称的后台进程。

因此,您不能也不应该根据可以在 NPAPI 插件中获得的 Carbon 窗口引用创建 NSWindow。 在这一点上阅读Apple's own documentation。您应该请求核心图形绘制方法,然后NP_CGContextWindowRef 字段应该有一个NSWindow*,而不是Carbon window ref。

【讨论】:

  • 对不起,我没有给出足够的代码行,实际上window->window是我带风的里面的NP_CGContext。但它不是 NSWindow,它是 HIObject,我使用的碳窗 ref。
  • 我当然要求核心显卡。我也尝试了可可事件,safari 给 ctx->window 值为零,无法使用可可事件模型在某处添加任何 NSView
  • 那我猜你不能使用NSView。
  • 感谢您的回答。有人有改变 NSWindow 行为的想法吗?我再说一遍,它可以在 Firefox 下运行!
  • 它可以在 Firefox 上运行,因为在这种情况下,插件仍然在“内部”Firefox 中运行。在 Safari 中,插件不再是 Safari 进程的一部分。所以你的插件不能访问 Safari 的窗口。因此,它在 Firefox 上运行的事实并不意味着新 Safari 上的任何东西。
【解决方案2】:

如果它可以在 Firefox 上运行,那就太令人震惊了,而且完全不受支持。它是否适用于 Firefox 4 及更高版本?

如果您绝对必须使用 NSView,我知道在插件中执行此操作的唯一方法是将 NSView 渲染到您的 CGContext 中。请记住,在带有 Cocoa 事件系统的较新的 NPAPI 浏览器中,您将 CGContextRef 作为绘图事件的一部分;要请求绘制事件,您可以调用 NPN_InvalidateWindow。

FireBreath 在 CGContextRef 中有一个 completely experimental and not-fully-functional example of rendering an NSView(特别是 WebView),您可以将其视为示例。

除了使用 CGContextRef,您唯一的选择是使用 CALayer;如果你能找到一种制作 NSWindow 或 NSView 的方法,你会没事的,但我不知道是否有。有人建议将 CALayer 设置为 NSView 的渲染层可能会起作用。无论哪种方式,您很可能都必须转发所有事件,因为您基本上将 NSView 托管在屏幕外视图中。

别搞错了; 不支持在浏览器中获取 NSView 的方法。从来没有——人们使用的方法不受支持,并且依赖于浏览器特定的 API 实现。当您使用类似的东西时,您可以可靠地预期它们最终会损坏,例如在这种情况下。有关绘图模型的更多信息,您可以read Stuart Morgan's blog post on the subject,查看FireBreath mac drawing model docs,或阅读Cocoa event model spec

【讨论】:

  • 无法将 NSWindow 或 NSView 放入 CALayer。您可以将 NSView 的内容绘制到 CALayer 中,就像您可以绘制到 CGContextRef 一样,但无论哪种方式,它都只是它的图片,因此(如您所说)需要事件转发。
  • 感谢您的回答。我要对我的客户说,safari、chrome 和越来越多的多进程导航器将不再支持他的软件。一次打开一个基于 NSView 的软件是 Cocoa 中正确的方法,因为它具有可以轻松使用插件的软件内核。今天我们的新软件需要一种新方法,或者每次都愚蠢地重写它们。
【解决方案3】:

鉴于您从“获取碳窗口参考”开始,您的方法注定要失败,因为它基于碳事件模型(不仅如此,还假设其内部实现细节)。任何在 64 位系统上运行 Firefox 的人都必须在 32 位模式下手动重新启动 Firefox 才能使您的 hack 工作,即使这样,它也只能在 Firefox 完全删除 Carbon 支持之前工作(计划在可预见的将来进行)。

正如其他答案所说,您出错的地方是您的整个方法完全不受支持,而且它曾经作为 NPAPI 插件工作的事实是幸运的。您根本无法在 NPAPI 插件中直接使用 NSView。

【讨论】:

  • 感谢您的回答。我要对我的客户说,safari、chrome 和越来越多的多进程导航器将不再支持他的软件。一次打开一个基于 NSView 的软件是 Cocoa 中正确的方法,因为它拥有一个可以轻松使用插件的软件内核。今天我们的新软件需要一种新方法,或者每次都愚蠢地重写它们。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-10
  • 1970-01-01
相关资源
最近更新 更多