[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-devel
Subject:    Re: QXEmbed and its many variants
From:       George Staikos <staikos () kde ! org>
Date:       2003-02-21 17:16:08
[Download RAW message or body]


Great work Leon!  I haven't tried it yet, but it's a thorough investigation 
into a problem I discovered myself last night as well.  I will test this 
patch tonight.


On Friday 21 February 2003 12:11, Leon Bottou wrote:
> EXECUTIVE SUMMARY
>
> There are two embedding cases: (a) embedding XEMBED aware applications,
> and (b) embedding applications that know nothing about XEMBED.
> With time these two cases have diverged.  Implementations of the first case
> no longer handle the second case properly. This is the root cause of the
> proliferation of QXEmbed derivatives.
>
> The attached patch for QXEmbed implements a choice of protocols.
> One can use XEMBED for embedding XEMBED aware applications
> or XPLAIN for non XEMBED aware applications.
>
> Together with minor patches, this change fixes bug 54375.
> Most importantly it provides a way to rationalize the many variants of
> QXEmbed. It does not solve all issues but clearly defines a framework for
> addressing them.
>
> MOTIVATION
>
> Some (all) netscape plugins no longer get keyboard events under kde-3.1.
> See bug <http://bugs.kde.org/show_bug.cgi?id=54375>
>
> After some research I found that the source of the problem
> is the replacement of the old knspluginembed class
> by the  standard embedding class qxembed.
>
> The problem is that qxembed implements the XEMBED protocol
> despite the fact that the embedded application, nspluginviewer,
> is completely unaware of this protocol.  This stems from the fact
> that the netscape plugin api dictates that nspluginviewer must
> essentially be a Xt/Motif application.
>
> The same mismatch occurs with java embedding.  Also I found
> several mailing list messages from people experiencing trouble
> embedding emacs, vim, or other non XEMBED aware applications.
>
> ANALYSIS
>
> The very first embedding codes were only relying on the X specification
> and were pretty much able to embed anything.  There were rough edges.
> Focus, for instance, was handled by the default X focus behavior which
> no longer matches the expectations set by modern toolkits.
>
> The QXEmbed code, and later the XEMBED specification, were
> designed to provide these missing features.  Several changes
> are introduced to do so:
> - The embeding application uses an invisible focus proxy window
>   to basically disable the default X focus behavior.
> - The embedded application is required to cooperate with
>   the embedding widget to obtain the keyboard focus.
>   Otherwise it never gets it.
>
> We must now recognize the presence of two different cases.
> Either we embed an XEMBED aware application, or we embed
> an application with no XEMBED support.  The embedding class
> must behave differently in these two cases.
>
> RESULTS
>
> The attached patches define the notion of protocol in the qxembed class.
> Two protocols are supported:
> - The default protocol is XEMBED and behaves as usual.
> - The second protocol is named XPLAIN and is designed to
>   support embedding of application that are not aware of embedding.
>   Of course this comes at the price of reduced functionalities.
>   Tab focus, for instance, is not supported.
>
> The only thing you have to do is to call
>   embedwidget->setProtocol(QXEmbed::XPLAIN);
> before calling embed().
>
> I chose not to implement a second class because I believe that
> the XEMBED protocol version 2 provides a way to test whether
> an application supports the XEMBED protocol.  We will then be
> able to determine automatically whether we should use XEMBED
> ot XPLAIN.  There will be no need then to use the setProtocol().
>
> I tested this new class with the nspluginviewer and the djvu plugin.
> To make it work I had to perform minor changes in nsplugins (attached)
> and slightly more changes in the djvu plugin nsdejavu.so (discussed later).
> Everything works nicely with these changes in place.
>
> I believe that these changes also simplify the embedding
> code in KJavaAppletWidget because the XPLAIN protocol
> borrows a lot from this work.
>
> Most importantly I believe that these changes provide a clean
> way to eliminate the many semi-buggy variants of QXEmbed
> and to consolidate all the bug fixes in a single code base.
>
>
> UNRESOLVED ISSUES
>
> A still unresolved issue bites us when the embedded application
> (i.e. nspluginviewer) itself embeds a third application
> (i.e. djview, acroread, mplayer) using an ad-hoc protocol.
>
> The XEMBED specification demands that toolkits call
> XSetInputFocus() to redirect the X11 focus to an invisible
> focus proxy window.  Doing so completely disables
> the default focus mechanisms of X11.  These default
> mechanisms were the cause of much trouble for XEMBED.
> But these defaults mechanisms were relied upon by
> the ad-hoc embedding protocols.
>
> Currently the XPLAIN protocol makes sure that the toplevel window
> of the embedded application receives the KeyPress and KeyRelease
> events it needs.  The application then must explicitly forward them to
> the relevant widgets.  Some applications however relied on the
> default X11 focus mechanisms to do that.  These must be modified.
>
> For instance you can see explicit fowarding code in my changes
> to the nspluginviewer (see attachement) and also in my changes to the djvu
> plugin. (see
> <http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/djvu/djvulibre-3.5/gui/nsde
>javu/nsdejavu.c.diff?r1=1.17&r2=1.18>)
>
> There might be a way to solve this problem by temporarily setting the
> X11 focus to the embedding widget when this widget has the logical input
> focus. But to do so we need to define a method for negotiating this
> operation with the toolkit of the embedding application.  More precisely I
> know how to take the X11 input focus but I do not know how to put it back.
>
> Should such a negotiation method be defined, we would simply update
> the implementation of the XPLAIN protocol in QXEmbed and
> forget about the above problems.
>
> CONCLUSION
>
> This QXEmbed change solve a few pending bugs.
> Most importantly it provides a way to rationalize the many variants of
> QXEmbed. It does not solve all issues but clearly defines a framework for
> addressing them.
>
>
> - Leon Bottou
>
>
>
> P.S. -- [historical comments]
>
> My first experience with embedding dates from the first djvu plugin.
> Here is an interesting email exchange.  I wonder sometimes...
>
> -----------------------
> Date: Tue, 06 Oct 1998 16:01:17 -0400
> From: Leon Bottou <leonb@research.att.com>
> To: info@troll.no
> Subject: [SUGGESTION] About QXtWidget in a mostly Qt application (qt-1.40)
>
> Your doc (QXtWidget) says that
> "Note that the parent must be a QXtWidget (possibly NULL). "
> "This is necessary since all Xt widgets must have Xt       "
> "widgets as ancestors up to the top-level widget.          "
> "WWA: This restriction may be avoidable by reimplementing  "
> "the low-level Qt window creation/destruction functions.   "
>
> This is not exactly right. There is a (strange) way
> to create a Xt widget whose ancestor (in the window tree)
> is not a Xt widget but a regular X window.
> The trick involves creating a toplevel widget and reparenting
> its window before it ever gets mapped.
>
> Here is the procedure ....
>
> n=0;
> XtSetArg(args[n], XmNwidth, width); n++;
> XtSetArg(args[n], XmNheight, height); n++;
> XtSetArg(args[n], XmNoverrideRedirect, True); n++;  // avoid WM interaction
> XtSetArg(args[n], XmNmappedWhenManaged, False); n++;
> XtSetArg(args[n], XmNvisual, visual); n++;
> XtSetArg(args[n], XmNcolormap, colormap); n++;
> XtSetArg(args[n], XmNdepth, depth); n++;
> shell=XtAppCreateShell("coolwidget", "coolwidget",
> 			topLevelShellWidgetClass,
> 			display, args, n);
> XtRealizeWidget(shell);
> XSync(displ, False);	// I want all windows to be created now
> XReparentWindow(displ, XtWindow(shell), parentwindow, 0, 0);
> XtSetMappedWhenManaged(shell, True);
> XtMapWidget(shell);
>
> You can then build a complete Xt widget hierarchy
> [assumming that your event loop properly dispatches events]
> You must of course make sure to unmap the widget
> and reparent it back to the rootwindow
> before destroying these windows.
> Hope you can use this ...
> Sincerely,
>
> -----------------------
> To: Leon Bottou <leonb@research.att.com>
> Date: Thu, 08 Oct 1998 19:11:01 +0200
> From: Warwick Allison <warwick@troll.no>
> Subject: Re: [SUGGESTION] About QXtWidget in a mostly Qt application
> (qt-1.40)
>
> Leon Bottou wrote:
> >This is not exactly right. There is a (strange) way
>
> Interesting stuff.  I'm looking into using this technique - thanks!
> Warwick

-- 

George Staikos

 
>> Visit http://mail.kde.org/mailman/listinfo/kde-devel#unsub to unsubscribe <<
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic