2017-07-18 167 views
0

根据设计要求,我正在FLTK中开发一个GUI,它必须有一个主(父)窗口,一个子窗口和一个X Window,它是孩子的​​孩子窗口。这是在Ubuntu 16.04。FLTK:XLib错误,带有多个Fl_Windows的X窗口初始化

使用此设置运行我的原始项目会产生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窗口。这里是控制台输出:

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窗口通过自己的行为罚款:

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窗口作为父项时才起作用?

+0

想想问一下[FLTK](http://www.fltk.org/newsgroups.php?gfltk.general+T) –

+0

@Basile Starynkevitch我会这样做的。感谢您的建议。 – bcdan

+0

您正在将FLTK与低级别的X11 API混合使用。这没有意义。为什么你需要'XOpenDisplay'' XCreateSimpleWindow'和所有这些?! –

回答

0

问题是XOpenDisplay被调用两次。作为初始化过程的一部分,FLTK将打开显示屏,并通过初始化X窗口将系统搞乱,再次调用它。

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