2017-07-18 168 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