1

I`ve created simple hello world-like plugin which draws red box.

Аfter embedding into xulrunner application the plugin works almost fine. Xulrunner application successfully redraws the box on resizing the application window.

But after any mouse event, for instance - left click, my application crashes with "Stack overflow". Debugger says the reason is endless cycle of 2 calls of forwardMethod followed by one call of JSD_GetValueForObject

After the crash stack contents is the next:

  • -[NSApplication _indexOfWindow:]
  • -[NSEvent window]
  • JSD_GetValueForObject
  • JSD_GetValueForObject
  • JSD_GetValueForObject
  • forwardMethod
  • forwardMethod
  • JSD_GetValueForObject
  • forwardMethod
  • forwardMethod
  • JSD_GetValueForObject
  • forwardMethod
  • forwardMethod
  • JSD_GetValueForObject
  • forwardMethod
  • forwardMethod
  • JSD_GetValueForObject
  • forwardMethod
  • forwardMethod
  • JSD_GetValueForObject
  • forwardMethod
  • forwardMethod
  • .....etc

My code is:

int16_t NPP_HandleEvent(NPP instance, void* event)
{
    EventRecord* carbonEvent = (EventRecord*)event;

    if (carbonEvent && (carbonEvent->what == updateEvt))
    {       
        PluginInstance* currentInstance = (PluginInstance*)(instance->pdata);
        CGContextRef cgContext = ((NP_CGContext*)(currentInstance->window.window))->context;
        float windowWidth = currentInstance->window.width;
        float windowHeight = currentInstance->window.height;

        static int x = 0;

        if (x++)
            return;

        NPRect clipRect = currentInstance->window.clipRect;

        NP_CGContext* npContext = currentInstance->window.window;

        NSWindow* browserWindow = [[[NSWindow alloc] initWithWindowRef:npContext->window] autorelease];

        int y = [browserWindow frame].size.height - (clipRect.bottom - clipRect.top) -  currentInstance->window.y;

        //[plugin attachToWindow:browserWindow at:NSMakePoint(window->x, y)];
        NSPoint point = NSMakePoint(currentInstance->window.x, y);

        // find the NSView at the point
        NSView* hitView = [[browserWindow contentView] hitTest:NSMakePoint(point.x+1, point.y+1)];
        if (hitView == nil || ![[hitView className] isEqualToString:@"ChildView"]) 
        {
            x = 0;
            return;
        }

        NSView* parentView = hitView;       

        NSBox *box = [[NSBox alloc] initWithFrame:NSMakeRect(0.0, 0.0, 100, 100)];
        [box setBoxType:NSBoxCustom];
        [box setBorderType:NSLineBorder];
        [box setTitlePosition:NSNoTitle];
        [box setFillColor:[NSColor redColor]];

        [parentView addSubview:box];

        //DrawPlugin(cgContext, windowWidth, windowHeight);
    }

    return 0;
}
Wladimir Palant
  • 56,865
  • 12
  • 98
  • 126
Mischa
  • 43
  • 1
  • 6
  • 1
    `EventRecord` isn't a Carbon event record—it's a *pre-*Carbon event record. That is, it's the type from Toolbox's Event Manager. While that Event Manager does still exist in Carbon (in 32-bit), the true “Carbon Event Manager” is a separate API with its own opaque `EventRef` type. – Peter Hosey Nov 20 '09 at 16:02
  • Thank you, Peter for your comment. Maybe the problem could be solved after switching to the true Carbon Event model...If it is possible.... – Mischa Nov 21 '09 at 09:20
  • I tried the next code in Debugger: NPError NPP_New(...) { NPBool supportsCoreGraphics; if (browser->getvalue(instance, NPNVsupportsCoreGraphicsBool, &supportsCoreGraphics) != NPERR_NO_ERROR) supportsCoreGraphics = FALSE; NPBool supportsCarbon; if (browser->getvalue(instance, NPNVsupportsCarbonBool, &supportsCarbon) != NPERR_NO_ERROR) supportsCarbon = FALSE; return 0; } After the the debugger stopped on "return" the supportsCarbon = false !!! I tried latest stable version of xulrunner and even the latest Beta version and the result remains always the same. – Mischa Nov 21 '09 at 10:00
  • So plugins can not even support true carbon event model. Strange, very strange.... Maybe i`m doing something wrong? – Mischa Nov 21 '09 at 10:02

3 Answers3

3

Thank you, Winz, very much!

I`ve just downloaded the latest mozilla build and SDK from

http://ftp.mozilla.org/pub/mozilla.org/xulrunner/nightly/latest-trunk/

And BasicPlugin.xcodeproj from

http://mxr.mozilla.org/mozilla-central/source/modules/plugin/sdk/samples/basic/mac/

Cocoa event model is now accessible.

Mischa
  • 43
  • 1
  • 6
  • Yes I used the latest build and not the lastest beta. I was trying to get a pointer on a NSView before sending you a email, but I have not succeded yet. Moreover in the source code of firefox there is an other class called nsview too! Do not hesitate to edit or post an answer to tell us how you embedded your application ^_^ – Winz Nov 23 '09 at 13:11
1

I do not think that Cocoa and the old EventRecord system mix together very well.

A cocoa event model is now avalaible in the last build of mozilla.

Check-out the tree for comm-central with Mercurial and try it:
hg clone http://hg.mozilla.org/mozilla-central/ src
The path to the Xcode project is:
src/modules/plugin/sdk/samples/basic/mac/
and the plugin must be copied to:
/Library/Internet Plug-Ins/

I tried it myself with the basic firefox plugin and the cocoa event system works.
I just do not know how to get a pointer to the current NSView.

I think it had to be done for the 64 bits version of Firefox on mac. It is not available in Firefox 3.6, but might be in Firefox 3.7, and the version of the NPAPI SDK with the Cocoa event model is the version 0.23.

EDIT:
To try it directly without mercurial download the latest mozilla build as Misha at:
http://ftp.mozilla.org/pub/mozilla.org/xulrunner/nightly/latest-trunk/
The Xcode project with the Cocoa event model is at:
http://mxr.mozilla.org/mozilla-central/source/modules/plugin/sdk/samples/basic/mac/

The NetscapeCocoaPlugin sample in the Webkit sources use the cocoa event model too.

Winz
  • 496
  • 1
  • 6
  • 7
  • Actually Cocoa event model is not supported under 32 bit. That is why all of the 32 bit cocoa plugins have to use Carbon event model and can`t use such great things like CoreAnimation which require Cocoa event model. – Mischa Nov 20 '09 at 15:40
  • 1
    Mischa: Do you mean in Netscape plug-ins? It's supported under 32-bit just fine in applications. – Peter Hosey Nov 20 '09 at 16:00
  • 1
    It is not a carbon event model, which uses EventRef. EventRecord is a legacy model from "Classic" Mac OS. – Winz Nov 20 '09 at 17:10
  • >Mischa: Do you mean in Netscape plug-ins? Of cource, yes, in Netscape plugins. It is only the problem of the Netscape Cocoa 32bit plugins. – Mischa Nov 21 '09 at 09:11
  • Thank you, Winz! Could you please tell me exactly which version of Mozilla you used? And it would be great if you give a sample hello-world like Xcode project for download - or simply e-mail it to me ( mihuil@ngs.ru ). I`ve got a feeling that i`m doing something wrong with the Xcode settings or something. – Mischa Nov 21 '09 at 10:54
  • ... because i`ve already tried the latest versions of Xulrunner, including the latest beta version and NPNVsupportsCocoaBool test always returned false. – Mischa Nov 21 '09 at 10:57
  • Gecko 1.9.3 is the first version to support the Cocoa event model. – smorgan May 18 '10 at 18:14
0

I just do not know how to get a pointer to the current NSView

Hello, Winz!

The answer seems to be obvious- we can obtain NSView using EventRecord legacy event model and AFTER THAT switch to Cocoa event model by adding the line:

browser->setvalue(instance, NPPVpluginEventModel, (void*)NPEventModelCocoa);

My application become absolutely stable after that. No more crashes!!!

I`ve just received an NPCocoaEventDrawRect after activating the main window of my application. So the cocoa event model seems to work.

Mischa
  • 43
  • 1
  • 6
  • 1
    I will test that, thank you. I tried with the sample "NetscapeCocoaPlugin" from the lastest Webkit sources: a call to [NSView focusView] in NPP_SetWindow returns the current NSView too. – Winz Nov 25 '09 at 15:40
  • You should absolutely not do this. Per https://wiki.mozilla.org/NPAPI:Models "Changing models outside of NPP_New is not allowed." The fact that it is working for you is an accident of implementation. You cannot get a pointer to the native NSView under the Cocoa event model, and that's by design. Any workaround you manage to come up with is going to fail as soon your plugin is run out of process. – smorgan May 18 '10 at 17:41