From kde-core-devel Sun Jul 14 21:33:05 2002 From: Till Krech Date: Sun, 14 Jul 2002 21:33:05 +0000 To: kde-core-devel Subject: QXEmbed reparent patch X-MARC-Message: https://marc.info/?l=kde-core-devel&m=102668239329318 MIME-Version: 1 Content-Type: multipart/mixed; boundary="--Boundary-00=_R4eM9is3cxXeLGe" --Boundary-00=_R4eM9is3cxXeLGe Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline 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=20 QXEmbed::embed() is called, the movies are not always embedded but appear i= n=20 a toplevel window managed by the windowmanager. I think that this is the same problem why applets are not always embedded w= hen=20 running konqi under sawfish/gnome. The trick is, to retry to XReparentWindow the window for up to 50 times wit= h=20 slight delays (usleep(1000)) and look if it has already the required parent= =20 with XQueryTree. Could you please look at the attached patch, if it solves the problem or if= it=20 is just a workaround. Some Xlib knowledge required. regards, till =20 =2D-=20 SuSE Linux 8.0 (i386) 2.4.18-64GB-SMP KDE: 3.0.6 (KDE 3.1 alpha1) Qt: 3.0.6-snapshot-20020712 --Boundary-00=_R4eM9is3cxXeLGe Content-Type: text/x-diff; charset="us-ascii"; name="qxembed-reparent.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="qxembed-reparent.patch" ? 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 #include #include @@ -34,6 +33,23 @@ #define XK_MISCELLANY #define XK_LATIN1 #include +#include +//#include +//#include +#include + +#ifdef HAVE_UNISTD_H +#include +#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 /*! 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 ) { --Boundary-00=_R4eM9is3cxXeLGe--