FLTK:使用多个Fl_Windows

时间:2017-07-18 12:26:05

标签: c++ x11 xlib fltk

根据设计要求,我在FLTK中开发一个GUI,它必须有一个主(父)窗口,一个子窗口和一个X Window,它是子窗口的子窗口。这是在Ubuntu 16.04。

使用此设置运行我的原始项目会产生XLib错误BadWindow (invalid Window parameter) (Details: serial 7 error_code 3 request_code 1 minor_code 0)

我有以下测试程序,只有与错误相关的功能再现了类似的错误:

#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Button.H>
#include <FL/x.H>

#include <iostream>

class ChildWindow : public Fl_Window {
public:
    ChildWindow() : Fl_Window(100, 100, 300, 200, "Child"){
        this->end();
        this->show();

        Display * dis = XOpenDisplay(NULL);

        std::cout << "Child XID: " << (void *)fl_xid(this) << '\n';
        std::cout << "XWindow XID: " << dis << '\n';

        Window win = XCreateSimpleWindow(dis, fl_xid(this),
            5, 5, 100, 100, 0, 0, 0);
        XMapRaised(dis, win);
        XSync(dis, false);
    }
};

class ParentWindow : public Fl_Window {
public:
    static ChildWindow * child;

    ParentWindow() : Fl_Window(100, 100, 400, 300, "Parent"){
        Fl_Button * b = new Fl_Button(10, 10, 70, 20, "Make Child");
        b->callback(CallbackMakeChild, NULL);
        this->add(b);
        this->end();
        this->show();

        std::cout << "Parent XID: " << (void *)fl_xid(this) << '\n';
    }

    static void CallbackMakeChild(Fl_Widget * w, void * o){
        child = new ChildWindow();
        child->show();
    }
};

ChildWindow * ParentWindow::child = NULL;

具有

的主要功能
int main(){
    ParentWindow parent;
    Fl::run();
}

运行时,上面的代码应该创建一个带按钮的窗口。按下该按钮时,将创建一个子窗口,并尝试创建X Window。这是控制台输出:

Parent XID: 0x4400002
Child XID: 0x4400005
XWindow XID: 0xe03140
X_CreateWindow: BadWindow (invalid Window parameter) 0x4400005
X_ConfigureWindow: BadWindow (invalid Window parameter) 0x4600001
X_MapWindow: BadWindow (invalid Window parameter) 0x4600001

子窗口和X Window本身表现良好:

int main(){
    ChildWindow child;
    Fl::run();
}

此代码(创建两个非分层窗口)也失败:

int main(){
    ChildWindow child1; // This window works
    ChildWindow child2; // This causes similar errors as above
    Fl::run();
}

我还尝试了fl_open_displayFl_Window::make_current的各种组合,但没有成功。

(所有代码,在一个文件中,通过运行./fltk-config --compile myprog.cpp进行编译)

此处的模式显示X窗口初始化为第一个FLTK窗口正常,但不适用于之后创建的窗口。我的猜测是它与FLTK如何与XLib接口/初始化有关,但我无法在文档中找到具体内容。

有没有人解释/解决为什么X Window初始化仅在使用首次创建的FLTK窗口作为父窗口时才有效?

1 个答案:

答案 0 :(得分:0)

问题是XOpenDisplay被调用了两次。 FLTK在初始化过程中打开显示,并通过初始化X窗口再次调用它来搞砸系统。

这是通过删除说dis = XOpenDisplay(NULL)的行并替换dis的引用来解决的,其中FLTK显示位于fl_display

相关问题