【问题标题】:FLTK: XLib error with X window initialization with multiple Fl_WindowsFLTK:X 窗口初始化与多个 Fl_Windows 的 XLib 错误
【发布时间】:2023-03-25 01:43:02
【问题描述】:

根据设计要求,我正在 FLTK 中开发一个 GUI,它必须有一个主(父)窗口、一个子窗口和一个 X 窗口,它是子窗口的子窗口。这是在 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 窗口。这是控制台输出:

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 窗口作为父窗口时才有效的解释/解决方案吗?

【问题讨论】:

  • 考虑在一些FLTK 群组中提出这个问题
  • @Basile Starynkevitch 我会这样做的。感谢您的建议。
  • 您正在将 FLTK 与低级 X11 API 混合使用。这是没有意义的。为什么你需要XOpenDisplay XCreateSimpleWindow 和所有这些?!
  • @n.m.需要低级接口的专有软件。我尝试使用 FLTK 句柄,但它们不适用于上述专有软件,所以我不得不使用其他东西。
  • 将我的 GUI 分解为单独的可执行文件是可行的,但我想看看我是否可以先解决原始问题。

标签: c++ x11 xlib fltk


【解决方案1】:

问题是XOpenDisplay 被调用了两次。 FLTK 作为初始化过程的一部分打开显示,并在初始化 X 窗口时再次调用它会破坏系统。

已通过删除表示 dis = XOpenDisplay(NULL) 的行并将对 dis 的引用替换为位于 fl_display 的 FLTK 显示来解决此问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-13
    • 2011-05-19
    • 1970-01-01
    • 2014-05-17
    • 1970-01-01
    • 1970-01-01
    • 2012-02-10
    相关资源
    最近更新 更多