PDA

View Full Version : QX11EmbedContainer problem



Martin42
8th December 2006, 09:05
Hi guys,

After having spent considerable time trying to debug this myself,
I have decided to post a question here.

I'm trying to embed a non-Qt X11 application into my own application
using QX11EmbedContainer. I'm using Qt4. Example:

QX11EmbedContainer *test=new QX11EmbedContainer(parent);
QProcess *process=new QProcess(test);
process->start(QString("/usr/bin/xclock"));

What happens is that the container widget is created perfectly, xclock
appears on the screen, but not inside the container. I read there are
keyboard focus limitations, but at least the xclock window should be
reparented if I am not mistaken. Other X11 tools (even qtconfig)
behave in the same manner.

I would be very grateful if someone could shed some light onto this!

Martin

jacek
8th December 2006, 11:22
IMO the problem is that the application you want to embed doesn't know about this, so you have to use QX11EmbedContainer::embedClient().

See attachment for a small test program (you can retrieve window id using xwininfo and paste it directly into line edit).

Martin42
8th December 2006, 11:54
Thank you for your reply and your example. However, the documentation states:

"Arbitrary (non-XEmbed) X11 widgets can also be embedded, but the XEmbed-specific features such as window activation and focus handling are then lost."

Every X Window manager reparents windows to 'swallow' them to put decoration around them, so I am convinced the Qt container widget is meant to do this too.

I would like to embed a text editor (more capable than QTextEdit) and cannot rewrite this to use QX11EmbedWidget.

Martin


IMO the problem is that the application you want to embed doesn't know about this, so you have to use QX11EmbedContainer::embedClient().

See attachment for a small test program (you can retrieve window id using xwininfo and paste it directly into line edit).

jacek
8th December 2006, 12:36
I would like to embed a text editor (more capable than QTextEdit) and cannot rewrite this to use QX11EmbedWidget.
I've never played with QX11EmbedWidget before, but it looks like you just have to know the window id of that editor. You probably can find it using some XLib calls (like XQueryTree()).

Martin42
8th December 2006, 13:43
If that is the way it works, then Qt is not very much of assistance here.

Well, I tried it anyway, getting the window id of a running application using xwininfo. Passing this to my application at least does something... The original window disappears but still does not appear in the container.

Having read something about bugs in this area in Qt 4 or 4.2 specifically, I was wondering whether anyone actually has experience with these calls.

Maybe a question to pass to one of the Qt developers?


I've never played with QX11EmbedWidget before, but it looks like you just have to know the window id of that editor. You probably can find it using some XLib calls (like XQueryTree()).

jacek
8th December 2006, 14:07
If that is the way it works, then Qt is not very much of assistance here.
It musn't be necessarily Qt's fault, but rather it's the way XEmbed works.


Having read something about bugs in this area in Qt 4 or 4.2 specifically, I was wondering whether anyone actually has experience with these calls.
Indeed it doesn't always work with Qt 4.2 (at least when I tried my test app with xclock), but I couldn't find anything in the task tracker.


Maybe a question to pass to one of the Qt developers?
It's hard to find them here. Better contact Trolltech support or try qt-interest mailing list.

Brandybuck
8th December 2006, 18:42
I have done this. If the window is not an XEmbedClient, then you need to know its window ID. You can get this with xwininfo or similar methods. I am attaching a sample program that does this, which I have used to embed XEmacs, xterm, etc.

XEmbed is intended for XEmbed-aware clients. Otherwise all it does is swallow apps, making it a poor-man's window manager.

p.s. There was a bug in 4.2.0-rc1, but it has been resolved.

Martin42
8th December 2006, 19:31
Compiling you example has been extremely helpful, thanks. It worked! I had in fact tried the following code earlier:

QX11EmbedContainer *test=new QX11EmbedContainer(parent);
test->embedClient(winid);
test->show();

which is very very similar, but doesn't work. The only difference I can think of is that in my case, there has not been time enough for the container window to be realised, so the embedding fails. It seems you need to wait for the container to appear on screen. That will probably be possible some way.

Next is the problem of knowing the winid of the process you forked, automatically, as I can't expect my users to use xwininfo....

Cheers.

Martin


I have done this. If the window is not an XEmbedClient, then you need to know its window ID. You can get this with xwininfo or similar methods. I am attaching a sample program that does this, which I have used to embed XEmacs, xterm, etc.

XEmbed is intended for XEmbed-aware clients. Otherwise all it does is swallow apps, making it a poor-man's window manager.

p.s. There was a bug in 4.2.0-rc1, but it has been resolved.

Brandybuck
8th December 2006, 20:56
It seems you need to wait for the container to appear on screen.
The client needs the container's X11 window to be embedded into. From your behavior, I'm assuming it isn't being created until the widget is shown for the first time. So either call show() before embedClient(), or embed the client in the showEvent() method.

Martin42
8th December 2006, 23:03
show() (immediately) before embedClient() doesn't work, so I will go for the latter.
Thanks for your help!

Martin


The client needs the container's X11 window to be embedded into. From your behavior, I'm assuming it isn't being created until the widget is shown for the first time. So either call show() before embedClient(), or embed the client in the showEvent() method.

yumiko
21st May 2007, 10:33
I have a similiar problem.

If I use "QProcess" to invoke an external application, how can I get the winId of that application?

marcel
21st May 2007, 10:58
You have to iterate through all the windows until you find it.

wysota
21st May 2007, 10:59
Either use X11 calls to get it or ask the process for it. Maybe it has a way of telling you its winId.

marcel
21st May 2007, 11:02
Either use X11 calls to get it or ask the process for it. Maybe it has a way of telling you its winId.
He can use at most the PID of the process.

yumiko
21st May 2007, 12:31
I want to embed an external application in my window. I use "QX11EmbedContainer" and "QProcess". However, it does not work. The application can be executed, but it isn't embedded in the container.
my code is :

QX11EmbedContainer container(0);
container.show();
QProcess proc(&container);
QString executable("kpdf");
QStringList arguments;
arguments << QString::number(container.winId());
proc.start(executable, arguments);

wagmare
2nd December 2008, 06:16
hi friends,
the program Mr.Brandybuck is excellent and its work fine in my app where i want to embed a GTK window to my Qt widget ..
is the window id of the GTK winow changes by time because i am entering window id of the running gtk window ...
if it changes by time or execution how can i get id of the external program (gtk)

wagmare
5th December 2008, 09:05
I have a similiar problem.

If I use "QProcess" to invoke an external application, how can I get the winId of that application?

this system call works fine after we start the external program by QProcess : xwininfo -root -all | grep ' " Window Title " ' |awk '{print $1}'

Window title is the running QProcess execution's title

in_dbasu
16th May 2011, 14:25
I am using the the container for a xEmbed Widget in the same scope and expect the widget to get embedded in the container but i am getting two window not a single window, the code is like this...
int main(int argc, char*argv[])
{
QApplication app(argc,argv)
QX11EmbedContainer container;
QX11EmbedWidget window;
container.show();
window.embedInto(container.WinID());
container.embedclient(window.winID());
int status= app.exec();
return status;
}

Ideally i shud be getting only a single window but i am getting two separate window.

What could be the problem????????