Mac OS X中的FLTK窗口共享相同的系统菜单

时间:2016-05-01 09:41:38

标签: macos user-interface fltk

当OS X中的某些应用程序有多个窗口(许多打开的文档,每个窗口都在自己的窗口中)时,它们似乎共享相同的系统菜单,至少在FLTK中。有没有办法找到最近选择的窗口从菜单发送事件?

这是我的设置(Mac OS X 10.6.2,FLTK 1.3.3):具有系统菜单的Shell类。每次打开新文档时,都会创建新的Shell

#ifdef __APPLE__
void Shell::macOpen(const char *fileName)
{
    // If there are empty shell, open the model in it
    if (s_empty != 0)
    {
        ...
        s_empty = 0;
    }
    // Otherwise, create new shell with the model
    else
    {
        char *args[1];
        args[0] = (char *) fileName;
        new Shell(1, args, s_conf, s_dct, fileName, 1);
    }
}
#endif

然后,我会跟踪最近选择的Shell将其保存到static Shell *Shell::s_current

int Shell::handle(int event)
{
    ...
    case FL_FOCUS:
#ifdef __APPLE__
        // We just selected some shell, it is current.
        s_current = this;
        cout << "Select shell with address: [" << s_current << "]" << endl;
#endif
        return 1;
    ...
}

这篇文章似乎有效,因为每次选择Shell时我都能看到痕迹:

Select shell with address: [0x8206db0]
Select shell with address: [0x82375f0]
Select shell with address: [0x5d20650]
Select shell with address: [0x82375f0]

现在,给定:

Shell *Shell::currentShell(Fl_Widget *w)
{
    cout << "Widget address: [" << w << "]" << endl;
    Shell *result = 0;
    if (w != 0)
    {
        result = (Shell *) w->window();
        cout << "Widget wingow address: [" << result << "]" << endl;
    }
#ifdef __APPLE__
    else
    {
        result = s_current;
        cout << "Last selected shell address: [" << result << "]" << endl;
    }
#endif
    return result;
}

我有一些回调:

void Shell::shortcutCB(Fl_Widget *w, void *data)
{
    cout << "Shortcut" << endl;
    Shell *ref = currentShell(w);
    if (ref != 0)
    {
         ...
    }
}

当从菜单执行此回调并且更多Shell s打开时,我收到以下错误:

Bus error

没有来自Shell::shortcutCBShell::currentShell的跟踪。当唯一的Shell打开时,一切都完美无缺。当更多Shell打开并且我关闭除了一个之外的所有时,错误再次出现。从Shell内的某个小部件调用相同的回调或从键盘快捷方式传递时,没有问题。

1 个答案:

答案 0 :(得分:0)

通过以下3个步骤解决了问题:

  1. 在OS X中声明manu bar也是静态的(这是失败的):

    #ifdef __APPLE__
        static Fl_Sys_Menu_Bar *s_menubar;
    #else
        Fl_Sys_Menu_Bar *m_menubar;
    #endif
    
  2. 不仅会在Shell::s_current事件中保存当前FL_FOCUS,还会保存Shell处理的任何事件,即每次返回1:

    int Shell::handle(int event)
    {
        int result = 0;
        switch (event)
        {
            // Set result = 1 when handling the event
            ...
        }
    #ifdef __APPLE__
        if (result == 1)
        {
            // We just selected some shell, it is current.
            s_current = this;
            cout << "Select shell with address: [" << s_current << "]" << endl;
        }
    #endif
        return result;
    }
    
  3. 在OS X上使用Shell::s_current进行菜单回调,无论是否生成呼叫小部件:

    Shell *Shell::currentShell(Fl_Widget *w)
    {
        Shell *result = 0;
    #ifdef __APPLE__
        result = s_current;
        cout << "Last selected shell address: [" << result << "]" << endl;
    #else
        cout << "Widget address: [" << w << "]" << endl;
        if (w != 0)
        {
            result = (Shell *) w->window();
            cout << "Widget wingow address: [" << result << "]" << endl;
        }
    #endif
        return result;
    }