Safari 5.1 npapi issue
Since several days I am trying to resolve the folowing issue, reading all I found around the web about npapi on mac.
The goal is to have a npapi plugin which works for safari and firefox(mac). My software (that I can not rewrite specialy for this purpose hase about 45000 lines of C code) is based on a NSView attached to a NSDocument....
I have a webkit version based plugin that I must trash (thanks to Apple!) based to the same NSView.
I have a npapi version plugin which works fine on firefox. In this npapi plugin, I take the carbon window ref, I make a NSWindow based on that: NSWindow *bro开发者_如何学运维wserWindow = [[[NSWindow alloc] initWithWindowRef:wind]autorelease];
and I put my NSView on this window and that works.
Now the pb is that I can not do the same thing on safari.
Look at attached picture, the window is not in the safari's window!
I tryed several ways... it dose not work. Can a cocoa's gourou says where I am making something wrong? or is this a known issue?
NPError NPP_SetWindow(NPP instance, NPWindow* window){
NP_CGContext *ctx = window->window; void *wind = ctx->window;
... in the NSView init function:
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;
In Safari 5.1, the web rendering is not done by Safari itself, but on a different process to enhance security. Open up the Activity Monitor, and you see that background process called "Safari Web Process" or something like that.
So, you can't and shouldn't create NSWindow
based on the Carbon window ref which can be obtained within NPAPI plugin.
Read Apple's own documentation on this point. You should request the core graphics drawing method, and then the WindowRef
field of NP_CGContext
should have a NSWindow*
, not the Carbon window ref.
If it works on Firefox, that's totally shocking and completely unsupported. Does it work in Firefox 4 and later?
If you absolutely have to use an NSView, the only way that I know to do it in a plugin is to render the NSView into your CGContext. Keep in mind that in newer NPAPI browsers with the Cocoa event system you get the CGContextRef as part of the draw event; to request a draw event you can call NPN_InvalidateWindow.
FireBreath has a completely experimental and not-fully-functional example of rendering an NSView (ans specifically a WebView) into a CGContextRef that you could look at as an example.
Other than using a CGContextRef your only other choice is to use a CALayer; if you can find a way to make a NSWindow or NSView in that you could be okay, but I don't know if there is one. Someone suggested that setting the CALayer as the rendering layer for the NSView might work. Either way you'll most likely have to forward all the events since you are basically hosting the NSView in an offscreen view.
Make no mistake; there is no supported way to get an NSView in the browser. There never has been -- methods that people have used were unsupported and depended on browser-specific implementations of the API. When you use things like that, you can reliably expect them to eventually break, such as in this case. For more information on the drawing models, you could read Stuart Morgan's blog post on the subject, check out the FireBreath mac drawing model docs, or read the Cocoa event model spec.
Given that you start with "take the carbon window ref", your approach is doomed, because it is based on the Carbon event model (and not just that, but assumptions about its internal implementation details). Anyone running Firefox on a 64-bit system will have to manually restart Firefox in 32-bit mode for your hack to work, and even then it will only work until Firefox completely removes Carbon support (which is planned for the foreseeable future).
As the other answers said, where you are going wrong is that your whole approach is completely unsupported, and the fact that it ever worked at all as an NPAPI plugin was luck. You simply cannot use an NSView directly in an NPAPI plugin.
精彩评论