src/gui/kernel/qwidget_x11.cpp
changeset 18 2f34d5167611
parent 3 41300fa6a67c
child 19 fcece45ef507
--- a/src/gui/kernel/qwidget_x11.cpp	Tue Feb 02 00:43:10 2010 +0200
+++ b/src/gui/kernel/qwidget_x11.cpp	Fri Apr 16 15:50:13 2010 +0300
@@ -1,6 +1,6 @@
 /****************************************************************************
 **
-** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
 ** All rights reserved.
 ** Contact: Nokia Corporation (qt-info@nokia.com)
 **
@@ -346,11 +346,6 @@
     qt_x11_enforce_cursor(w, false);
 }
 
-static Bool checkForConfigureAndExpose(Display *, XEvent *e, XPointer)
-{
-    return e->type == ConfigureNotify || e->type == Expose;
-}
-
 Q_GUI_EXPORT void qt_x11_wait_for_window_manager(QWidget* w)
 {
     if (!w || (!w->isWindow() && !w->internalWinId()))
@@ -363,38 +358,60 @@
     if (!w->testAttribute(Qt::WA_WState_Created))
         return;
 
-    if (!(w->windowFlags() & Qt::X11BypassWindowManagerHint)) {
-        // if the window is not override-redirect, then the window manager
-        // will reparent us to the frame decoration window.
-        while (!XCheckTypedWindowEvent(X11->display, w->effectiveWinId(), ReparentNotify, &ev)) {
-            if (t.elapsed() > maximumWaitTime)
-                return;
-            qApp->syncX(); // non-busy wait
-        }
-    }
-
-    while (!XCheckTypedWindowEvent(X11->display, w->effectiveWinId(), MapNotify, &ev)) {
-        if (t.elapsed() > maximumWaitTime)
-            return;
-        qApp->syncX(); // non-busy wait
-    }
-
-    qApp->x11ProcessEvent(&ev);
-
-    // ok, seems like the window manager successfully reparented us, we'll wait
-    // for the first paint event to arrive, while handling ConfigureNotify in
-    // the arrival order
-    while(1)
-    {
-        if (XCheckIfEvent(X11->display, &ev, checkForConfigureAndExpose, 0)) {
+    WId winid = w->internalWinId();
+
+    // first deliver events that are already in the local queue
+    QApplication::sendPostedEvents();
+
+    // the normal sequence is:
+    //  ... ConfigureNotify ... ReparentNotify ... MapNotify ... Expose
+    // with X11BypassWindowManagerHint:
+    //  ConfigureNotify ... MapNotify ... Expose
+
+    enum State {
+        Initial, Reparented, Mapped
+    } state = Initial;
+
+    do {
+        if (XEventsQueued(X11->display, QueuedAlready)) {
+            XNextEvent(X11->display, &ev);
             qApp->x11ProcessEvent(&ev);
-            if (ev.type == Expose)
-                return;
+
+            if (w->windowFlags() & Qt::X11BypassWindowManagerHint) {
+                switch (state) {
+                case Initial:
+                case Reparented:
+                    if (ev.type == MapNotify && ev.xany.window == winid)
+                        state = Mapped;
+                    break;
+                case Mapped:
+                    if (ev.type == Expose && ev.xany.window == winid)
+                        return;
+                    break;
+                }
+            } else {
+                switch (state) {
+                case Initial:
+                    if (ev.type == ReparentNotify && ev.xany.window == winid)
+                        state = Reparented;
+                    break;
+                case Reparented:
+                    if (ev.type == MapNotify && ev.xany.window == winid)
+                        state = Mapped;
+                    break;
+                case Mapped:
+                    if (ev.type == Expose && ev.xany.window == winid)
+                        return;
+                    break;
+                }
+            }
+        } else {
+            if (!XEventsQueued(X11->display, QueuedAfterFlush))
+                qApp->syncX(); // non-busy wait
         }
         if (t.elapsed() > maximumWaitTime)
             return;
-        qApp->syncX(); // non-busy wait
-    }
+    } while(1);
 }
 
 void qt_change_net_wm_state(const QWidget* w, bool set, Atom one, Atom two = 0)
@@ -1084,7 +1101,7 @@
         } else {
             // release previous focus information participating with
             // preedit preservation of qic
-            QInputContext *qic = inputContext();
+            QInputContext *qic = QApplicationPrivate::inputContext;
             if (qic)
                 qic->widgetDestroyed(this);
         }