1

我已经创建了简单的 hello world-like 插件,它绘制了红色框。

嵌入到 xulrunner 应用程序后,插件几乎可以正常工作。Xulrunner 应用程序在调整应用程序窗口大小时成功重绘了框。

但是在任何鼠标事件之后,例如左键单击,我的应用程序会因“堆栈溢出”而崩溃。调试器说原因是 2 次 forwardMethod 调用和 1 次 JSD_GetValueForObject 调用的无限循环

崩溃后的堆栈内容是下一个:

  • -[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

我的代码是:

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;
}
4

3 回答 3

3

谢谢你,温兹,非常感谢!

我刚刚从

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

和 BasicPlugin.xcodeproj 来自

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

Cocoa 事件模型现在可以访问了。

于 2009-11-23T11:31:51.163 回答
1

我不认为 Cocoa 和旧的 EventRecord 系统混合得很好。

可可事件模型现在在 Mozilla 的最后一个版本中可用。

使用Mercurial查看 comm-central 的树并尝试:
hg clone http://hg.mozilla.org/mozilla-central/ src
Xcode 项目的路径是:
src/modules/plugin/sdk/samples/ basic/mac/
插件必须复制到:
/Library/Internet Plug-Ins/

我自己尝试了基本的 firefox 插件,并且 cocoa 事件系统可以正常工作。
我只是不知道如何获得指向当前 NSView 的指针。

我认为必须在 mac 上为 64 位版本的 Firefox 完成。它在 Firefox 3.6 中不可用,但可能在 Firefox 3.7 中可用,并且带有 Cocoa 事件模型的 NPAPI SDK 版本是 0.23 版本。

编辑:
要直接尝试,无需反复下载最新的 mozilla 构建为 Misha:
http
://ftp.mozilla.org/pub/mozilla.org/xulrunner/nightly/latest-trunk/ 带有 Cocoa 事件模型的 Xcode 项目是在: http:
//mxr.mozilla.org/mozilla-central/source/modules/plugin/sdk/samples/basic/mac/

Webkit 源代码中的 NetscapeCocoaPlugin 示例也使用 cocoa 事件模型。

于 2009-11-20T15:23:57.937 回答
0

我只是不知道如何获得指向当前 NSView 的指针

你好,温兹!

答案似乎很明显——我们可以使用 EventRecord 遗留事件模型获取 NSView,然后通过添加以下行切换到 Cocoa 事件模型:

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

之后我的应用程序变得绝对稳定。没有更多的崩溃!

在激活我的应用程序的主窗口后,我刚刚收到一个 NPCocoaEventDrawRect。所以可可事件模型似乎有效。

于 2009-11-25T05:16:22.223 回答