0
votes

I'm trying to create an NPAPI plugin to listen to the Media Keys on a macbook and pass that to javascript to control things like pandora or soundcloud. I'm using Spotify's SPMediaKeyTap library, which just wraps CGEventTap running on a separate thread.

My problem is that I use npn_invoke to call back to javascript. This works normally, but when it's triggered from the CGEventTap callback, it crashes the plugin. I realize this needs to be run from the plugin thread, and I've tried to pass it back to the main thread both by using [NSObject performSelectorOnMainThread] and [NSObject performSelector:onThread] with the thread i've stored away in the main plugin threads create method. Both of these solutions still crash on any npn call. Is there anything else that goes on when handling a CGEventTap event that causes state to be invalid for NPN browser interaction calls?

1
is there a stack trace of where it crashed? and sample code of how you're calling NPN_Invoke?taxilian
So in NPP_New i store away the thread using main_thread = [NSThread currentThread]; then in the handler for SPMediaKeyTap, i call [self performSelector:onThread:blahblah:] with main_thread and it crashes on this line: browser->getvalue(instance, NPNVWindowNPObject, &window); I'm not sure exactly how to get a stack trace in an NPAPI plugin...msfeldstein
It seems to crash when i access that browser object (NPNetscapeFuncs*). I think what's happening is that the key events come in in the main Chrome process, which cant access the browser variable which is in the plugin process. I get EXC_BAD_ACCESS/KERN_PROTECTION_FAILURE on that line. If i store the command away into a static variable, then check for it in HandleEvent and invoke the JS function there, it works fine. I just need some way to tell the plugin to do something in the plugin process from the UI process.msfeldstein

1 Answers

0
votes

Don't try to second guess the threading model by saving the thread like you are; just use performSelectorOnMainThread to call NPN methods. I do this all the time and it works fine, so I'm guessing that something with your method of cross-thread marshalling isn't working the way it needs to.