RE: [fltk.general] XLib error with X window initialization with multiple Fl_Windows [General Use]

31 views
Skip to first unread message

MacArthur, Ian (Leonardo, UK)

unread,
Jul 18, 2017, 9:56:09 AM7/18/17
to fltkg...@googlegroups.com


> Per design requirements, I am developing a GUI in FLTK that must have a
> main (parent) window, a child window, and an X Window that is the child
> of the child window. This is in Ubuntu 16.04.

> Running my original project with this setup produces the XLib error
> BadWindow (invalid Window parameter) (Details: serial 7 error_code 3
> request_code 1 minor_code 0)

> I have the following test program with only the features relevant to the
> error that reproduces a similar error:


Can you also describe what it is you actually want to achieve, please?

Your code fragment is OK for demonstrating the problem, but without a grasp of what it is you actually want to do, I'm having trouble thinking through what the issues are...


Anyway, in the meantime, some comments interspersed below...





> #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);


Um, this is probably not a Good Idea; at this point the display is already open for your application, so opening it again may not be helpful.

The fltk lib exports a global you can use to get at this...

extern Display *fl_display;

(See the "Operating System Issues" section of the manual for a few more details.)

You could try replacing references to "dis" with " fl_display" and see if it flies any better for you?


> 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);
> }
> };


You are calling this object a ChildWindow, but in fltk parlance a "child" window is usually nested inside a parent - this looks to mike like it will be a free-standing window in its own right (not a "child" in that sense.)

Or am I missing something obvious here?



> 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();


Explicitly adding "b" to the container window is probably redundant here due to the way fltk parents widgets, but likely harmless!


> 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;

> with the main function of

> int main(){
> ParentWindow parent;
> Fl::run();
> }




Leonardo MW Ltd
Registered Office: Sigma House, Christopher Martin Road, Basildon, Essex SS14 3EL
A company registered in England & Wales. Company no. 02426132
********************************************************************
This email and any attachments are confidential to the intended
recipient and may also be privileged. If you are not the intended
recipient please delete it from your system and notify the sender.
You should not copy it or use it for any purpose nor disclose or
distribute its contents to any other person.
********************************************************************

Daniel Winkelman

unread,
Jul 18, 2017, 12:10:49 PM7/18/17
to fltk.general, ian.ma...@leonardocompany.com
The problem ended up being the extra display initialization. I talked a little more about it in Albrecht Schlosser's thread and Stack Overflow. There is a piece of proprietary software that needs to have a graphic output through a window handle. I tried passing an FLTK handle through fl_xid, but the software did not accept it, so I tried using an X window instead.

I'm relatively new to FLTK, so thanks for the tips as well.

MacArthur, Ian (Leonardo, UK)

unread,
Jul 18, 2017, 12:38:37 PM7/18/17
to fltkg...@googlegroups.com
> The problem ended up being the extra display initialization.


Yes, makes sense; that's really not a "safe" thing to do once your app has the display open, so...


> I talked a
> little more about it in Albrecht Schlosser's thread and Stack Overflow.

Probably get more sense asking here direct, TBH.

My experience is that the ratio of "folks who know what they are talking about", as compared to "folks who *think* they know what they are talking about" is generally pretty high around here.
That has not always been my experience on SO in the past... (I *like* SO, but you need to proceed with caution!)


> There is a piece of proprietary software that needs to have a graphic
> output through a window handle. I tried passing an FLTK handle through
> fl_xid, but the software did not accept it, so I tried using an X window
> instead.


Again, check the "Operating System Issues" section of the manual, I think you can make this work by extracting the Window you need from the fltk global:

extern Window fl_window;

This value is set when your "ChildWindow" is mapped... though it will change to track the current fltk window, so you may need to make judicious use of Fl_Window::make_current(), or (perhaps better!) grab the value of fl_window whilst in the draw() method of your derived window (since if you are in the draw() method, the window you want *must* be the currently mapped one!)



Anyway - A quote from the docs:

<quote>

Drawing using Xlib

The following global variables are set before Fl_Widget::draw() is called, or by Fl_Window::make_current():

extern Display *fl_display;
extern Window fl_window;
extern GC fl_gc;
extern int fl_screen;
extern XVisualInfo *fl_visual;
extern Colormap fl_colormap;

You must use them to produce Xlib calls. Don't attempt to change them. A typical X drawing call is written like this:

XDrawSomething(fl_display, fl_window, fl_gc, ...);

</quote>


There's also a section in the docs "Using a Subclass of Fl_Window for Special X Stuff" that might be pertinent to your case, though it is coming at things from a slightly different direction to what you actually want, I think!

Greg Ercolano

unread,
Jul 18, 2017, 2:17:54 PM7/18/17
to fltkg...@googlegroups.com
On 07/18/17 09:38, MacArthur, Ian (Leonardo, UK) wrote:
> Anyway - A quote from the docs:
> <quote>
> Drawing using Xlib
>
> The following global variables are set before Fl_Widget::draw() is called, or by Fl_Window::make_current():
>
> extern Display *fl_display;
> extern Window fl_window;
> extern GC fl_gc;
> extern int fl_screen;
> extern XVisualInfo *fl_visual;
> extern Colormap fl_colormap;
>
> You must use them to produce Xlib calls. Don't attempt to change them. A typical X drawing call is written like this:
>
> XDrawSomething(fl_display, fl_window, fl_gc, ...);
>
> </quote>
>
> There's also a section in the docs "Using a Subclass of Fl_Window for
> Special X Stuff" that might be pertinent to your case, though it is
> coming at things from a slightly different direction to what you actually want, I think!

Perhaps the OP's proprietary app also needs the window to be physically
open and on the screen. And I don't think that happens until Fl::run()
has gotten some cpu, which makes it tricky to initialize a lib that
needs a window id for an /open/ window. (Usually involves intercepting
the draw() call for the window)

I know that after a window.show() call, fl_xid(window) will return
the window id, and both window.shown() and window.visible() will
return 1, even though the window is not open + visible on the screen.

I just ran a small test and found that after window.show() is called,
fl_xid(window) is valid, and both window.shown() and window.visible()
return 1, but the window is /not/ open yet. (One can prove this by
adding a sleep() or getchar() just after the window.show() call)

So it's possible the OP's prop program needs the window already open.
I'm not 100% sure we offer a method that detects when the window
is actually physically open, but I think it's safe to say that if
you intercept the draw() call, at that time for sure the window is
open, and it would therefore be "safe" to initialize a proprietary
library that assumes the window is open.

Albrecht Schlosser

unread,
Jul 18, 2017, 3:14:26 PM7/18/17
to fltkg...@googlegroups.com
On 18.07.2017 20:17 Greg Ercolano wrote:
>
> Perhaps the OP's proprietary app also needs the window to be physically
> open and on the screen. And I don't think that happens until Fl::run()
> has gotten some cpu, which makes it tricky to initialize a lib that
> needs a window id for an /open/ window. (Usually involves intercepting
> the draw() call for the window)
>
> I know that after a window.show() call, fl_xid(window) will return
> the window id, and both window.shown() and window.visible() will
> return 1, even though the window is not open + visible on the screen.
>
> I just ran a small test and found that after window.show() is called,
> fl_xid(window) is valid, and both window.shown() and window.visible()
> return 1, but the window is /not/ open yet. (One can prove this by
> adding a sleep() or getchar() just after the window.show() call)

That's exactly the reason why we added the wait_for_expose() method.
From the docs:

"Waits for the window to be displayed after calling show().

Fl_Window::show() is not guaranteed to show and draw the window on all
platforms immediately. Instead this is done in the background;
particularly on X11 it will take a few messages (client server
roundtrips) to display the window. Usually this small delay doesn't
matter, but in some cases you may want to have the window instantiated
and displayed synchronously.

Currently (as of FLTK 1.3.4) this method has an effect on X11 and Mac
OS. On Windows, show() is always synchronous."

<http://www.fltk.org/doc-1.3/classFl__Window.html#aafbec14ca8ff8abdaff77a35ebb23dd8>

> So it's possible the OP's prop program needs the window already open.
> I'm not 100% sure we offer a method that detects when the window
> is actually physically open,

see above

> but I think it's safe to say that if
> you intercept the draw() call, at that time for sure the window is
> open, and it would therefore be "safe" to initialize a proprietary
> library that assumes the window is open.

That should work as well, although it might be less intuitive to implement.

Daniel Winkelman

unread,
Jul 18, 2017, 6:02:23 PM7/18/17
to fltk.general, Albrech...@online.de
Thank you all for your help and explanations. I definitely have a better understanding of how things are implemented now. After reading what you have written, the documentation makes a lot more sense.

Since I already got my project to work, I'm not going to attempt to make any changes for the time being. But this will be very useful for the future if I have to write similar code, and for when I go back and clean/harden things up.

My experience is that the ratio of "folks who know what they are talking about", as compared to "folks who *think* they know what they are talking about" is generally pretty high around here.

I agree!
Reply all
Reply to author
Forward
0 new messages