New XEmbed classes

Leon Bottou leonb at nec-labs.com
Mon Nov 17 15:32:53 GMT 2003


On Monday 17 November 2003 03:24 am, you wrote:
> Hi, Leon.
> I couldn't really see the benefit of a client not being destroyed
> somehow when the container died, especially if the client does not speak
> XEmbed. :/ Are you aware of any examples where this would be useful?

I made that mistake a few months ago.
KDE system tray icons must survive the deletion of the system tray.

The current consensus is to call XAddToSaveSet for XEMBED embedded windows
and have the client detect when it gets reparented into the root window.
When this happens it should let the application know.
The question is about how to achieve this.

My suggestion, in the case of QXEmbed, would be to generate
a WM_DELETE_WINDOW message.  This would trigger QWidget::close
and can easily be controlled by rejecting the QCloseEvent.
In the case of your classes, you could call a virtual function whose
default implementation calls QWidget::close.

When using the XPLAIN protocol, the embedding class should
not call XAddToSaveSet and obey the QXEmbed::setAutoDelete
settings. 

As of today, the detection of the reparenting-to-root is not implemented
and both cases (XEMBED and XPLAIN) rely on the autoDelete code.
This has been posponed until after the release of KDE-3.2.
The system tray must work!

> >- Not all items in the focusData lists are focusable.
> >  See recent changes in qxembed.cpp.
>
> I looked up the changes, but couldn't find anything about this; what part
> of the code is affected by this issue?

See http://webcvs.kde.org/cgi-bin/cvsweb.cgi/kdelibs/kdeui/qxembed.cpp
Changes for release 1.58 and 1.59.
The idea is to rely on Qt's focusNextPrevChild() function
because this function knows how the focusData stuff works.

> >There is a deeper issue regarding client support:
> >* QXEmbed tries to make all toplevel windows support XEMBED.
> >  If it was a part of Qt, all Qt applications would then be embeddable.

> I'm not following here; all X11 windows are "embeddable", but the only
> windows that support XEmbed controlled by Qt / these new classes are those
> that inherit QtXEmbedContainer.
>
> Where is it that QXEmbed tries to make windows support XEmbed?

After calling QXEmbed::initialize(), all toplevel windows support the XEMBED protocol.
They set topData()->embedded when they intercept the XEMBED_EMBEDDED_NOTIFY message.
Starting from there they handle the XEMBED message as per the spec.
This is achieved using a low level x11 event filter as 
well as a application level Qt event filter.

> The client->container concept maps very naturally to the idea of having a
> seperate class for the client and the container. The code looks, IMHO,
> much nicer this way, and from and API stand point it's easier to use for
> people who haven't used XEmbed before.

Sure. The code is nicer but it does less.

With the QXEmbed way, you can embed any Qt application with minimal changes.
They just have to call QXEmbed::initialize() from main().
Such applications can be used on the desktop or embedded.

In the case of QtXEmbedContainer, you must twiddle you
toplevel window classes (KMainWindow etc) in order to 
either encapsulate them into a QtXEmbedContainer or
use multiple inheritance.  In both cases there will be hurdles.

> I myself had to spend lots of time trying to figure out how to use the
> existing QXEmbed class in KDE. :-P

That is because of inadequate documentation.

The first embedding classes were able to embed any application
using only the X protocol.  But there were nagging issues with
keyboard focus.  This is why the XEMBED protocol was invented.

But the new QXEmbed classes were no longer able to safely embed
non Qt applications (e.g. netscape plugins, java windows, gvim)
because these would not obey the XEMBED protocol.
We then had a proliferation of tweaked embedding classes.
People would fix QXEmbed and revert the fix a few days later 
because it broke something else.  Quite a mess for such
a critical and obscure piece of code.

I recognized the problem in february and added the XPLAIN protocol.
There is a long explanation in the mailing list:
<http://lists.kde.org/?l=kde-devel&m=104584743531077&w=2>

The final result is that QXEmbed is a class for embedding
the toplevel windows of other applications.  
There are two ways to achieve this:
- Using the XEMBED protocol if these toplevel windows support XEMBED.
  This is the case for Qt application that call QXEmbed::initialize().
- Using the XPLAIN protocol if these toplevel windows do not support XEMBED.  
  The price is a less complete support of focus navigation.
   
Currently you must call QXEmbed::setProtocol to choose one way over the other.  
This could be automatic if the _XEMBED_INFO property was correctly implemented.

I strongly believe that the client side of the XEMBED protocol should
be implemented in the Qt/X11 proper.  Receiving the XEMBED_EMBEDDED_NOTIFY
should initiate the protocol.  Being reparented to the root window should
terminate it.  There is already a flag for this in topData().

There is a lot of ugly code to handle the focusProxy and the keyboard tab navigation.  
This code uses event filters (X11 and Qt) to navigate around Qt's algorithms.
All this code would be drastically simpler if these algorithms 
were aware of the embedding case.

> >Lately I added a lot of documentation and fixes into QXEmbed.
> >Please feel free to look at it.  I cannot be certain that I documented
> >all the pitfalls, but I discussed a lot of them.
>
> I see. They are very interesting. I'm working myself through the change
> log since Matthias' 1.1. There haven't really been that many changes to
> qxembed.*, it seems.

I tried not to mix the commenting and the modifications of QXEmbed.
My main contribution is the XPLAIN code.  I also fixed a number of bugs
found by simply reading the code with the intention of commenting it.

> These QtXEmbed classes are released under LGPL (see the header)), so this
> should not be a problem. I would be glad to aid in maintaining these
> classes, were they to be part of KDE. I'm sure that I have something to
> add to the XEmbed discussions.

Perfect.

> (1) I see these Lnnnn tags in the comments; what are they for?

Cross-reference.  Comments often refer to other comments.
Since everything happens in event filters, most of the QXEmbed
algorithms are delocalized in several event filters or 
event processing routines.

> (2) Is it common for discussions about XEmbed to take part in a list like
> KFileManager dev?

Some happens in kfm-devel, some in kde-devel, some in kde-core-devel, some in kwin.
I am checking these lists once in a while.  Please cc me if you send something.

Hope it helps.

- L.






More information about the kde-core-devel mailing list