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

List:       kde-core-devel
Subject:    QXEmbed reparent patch
From:       Till Krech <till () snafu ! de>
Date:       2002-07-14 21:33:05
[Download RAW message or body]

Hi,

I discovered a problem in QXEmbed (kdelibs/kdeui/qxembed.cpp).
QXEmbed is now also used by the java applet server and the nspluginviewer.

Problem:
http://www.shockwave.com embeds several flash movies. Although 
QXEmbed::embed() is called, the movies are not always embedded but appear in 
a toplevel window managed by the windowmanager.

I think that this is the same problem why applets are not always embedded when 
running konqi under sawfish/gnome.

The trick is, to retry to XReparentWindow the window for up to 50 times with 
slight delays (usleep(1000)) and look if it has already the required parent 
with XQueryTree.

Could you please look at the attached patch, if it solves the problem or if it 
is just a workaround. Some Xlib knowledge required.

regards, till
 
-- 
SuSE Linux 8.0 (i386) 2.4.18-64GB-SMP
KDE: 3.0.6 (KDE 3.1 alpha1)
Qt: 3.0.6-snapshot-20020712

["qxembed-reparent.patch" (text/x-diff)]

? Makefile.am.till
? kqeventutil.cpp
? kqeventutil.h
? kxeventutil.cpp
? kxeventutil.h
? qxembed-reparent.patch
? qxembed.diff
Index: qxembed.cpp
===================================================================
RCS file: /home/kde/kdelibs/kdeui/qxembed.cpp,v
retrieving revision 1.28
diff -u -p -r1.28 qxembed.cpp
--- qxembed.cpp	2002/07/06 02:44:22	1.28
+++ qxembed.cpp	2002/07/14 21:10:12
@@ -19,7 +19,6 @@
     Boston, MA 02111-1307, USA.
 *****************************************************************************/
 
-#include "qxembed.h"
 #include <qapplication.h>
 #include <qptrlist.h>
 #include <qptrdict.h>
@@ -34,6 +33,23 @@
 #define XK_MISCELLANY
 #define XK_LATIN1
 #include <X11/keysymdef.h>
+#include <kdebug.h>
+//#include <kxeventutil.h>
+//#include <kqeventutil.h>
+#include <config.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#ifdef HAVE_USLEEP
+#define USLEEP(x) usleep(x)
+#else
+#define USLEEP(x) sleep(0)
+#endif // HAVE_USLEEP
+#else
+#define USLEEP(x) sleep(0)
+#endif // HAVE_UNISTD_H
+
+#include "qxembed.h"
 
 #ifndef XK_ISO_Left_Tab
 #define XK_ISO_Left_Tab                                 0xFE20
@@ -186,6 +202,8 @@ bool QXEmbedAppFilter::eventFilter( QObj
 
 static int qxembed_x11_event_filter( XEvent* e)
 {
+    //kdDebug() << "qxembed_x11_event_filter " << KXEventUtil::getX11EventInfo(e) << \
endl; +
     switch ( e->type ) {
     case XKeyPress: {
         int kc = XKeycodeToKeysym(qt_xdisplay(), e->xkey.keycode, 0);
@@ -588,8 +606,22 @@ static bool wstate_withdrawn( WId winid 
     return withdrawn;
 }
 
-
-
+static int get_parent(WId winid, Window *out_parent)
+{
+    Window root, *children=0;
+    unsigned int nchildren;
+    int st = XQueryTree(qt_xdisplay(), winid, &root, out_parent, &children, \
&nchildren); +    if (st) {
+        if (children) {
+            XFree(children);
+        }
+        return st;
+    } else {
+        // kdDebug() << QString("**** FAILED **** XQueryTree returns status \
%1").arg(st) << endl; +    }
+    return st;
+}
+#include <unistd.h>
 /*!
 
   Embeds the window with the identifier \a w into this xembed widget.
@@ -604,9 +636,9 @@ static bool wstate_withdrawn( WId winid 
  */
 void QXEmbed::embed(WId w)
 {
+    kdDebug() << "************************** Embed "<< QString("0x%1").arg(w, 0, 16) \
<< " into " << QString("0x%1").arg(winId(), 0, 16) << " window=" << \
QString("0x%1").arg(window, 0, 16) << " **********" << endl;   if (!w)
         return;
-
     XAddToSaveSet( qt_xdisplay(), w );
     bool has_window =  w == window;
     window = w;
@@ -616,8 +648,20 @@ void QXEmbed::embed(WId w)
             QApplication::flushX();
             while (!wstate_withdrawn(window))
                 ;
+        }
+        Window parent;
+        get_parent(w, &parent);
+        kdDebug() << QString(">>> before reparent: parent=0x%1").arg(parent, 0, 16) \
<< endl; +        for (int i = 0; i < 50; i++) {
+            Window parent = 0;
+            XReparentWindow(qt_xdisplay(), w, winId(), 0, 0);
+            if (get_parent(w, &parent) && parent == winId()) {
+               kdDebug() << QString(">>> Loop %1: reparent of 0x%2 into 0x%3 \
successful").arg(i).arg(w, 0, 16).arg(winId(), 0, 16) << endl; +               break;
+            }
+            kdDebug() << QString(">>> Loop %1: reparent of 0x%2 into 0x%3 \
failed").arg(i).arg(w, 0, 16).arg(winId(), 0, 16) << endl; +            USLEEP(1000);
         }
-        XReparentWindow(qt_xdisplay(), w, winId(), 0, 0);
         QApplication::syncX();
     }
 
@@ -662,6 +706,7 @@ bool QXEmbed::focusNextPrevChild( bool n
  */
 bool QXEmbed::x11Event( XEvent* e)
 {
+    //kdDebug() << "x11Event " << KXEventUtil::getX11EventInfo(e) << endl;
     switch ( e->type ) {
     case DestroyNotify:
         if ( e->xdestroywindow.window == window ) {



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

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