diff options
author | Denis Dzyubenko <denis.dzyubenko@nokia.com> | 2010-02-04 12:30:13 (GMT) |
---|---|---|
committer | Denis Dzyubenko <denis.dzyubenko@nokia.com> | 2010-02-04 15:04:54 (GMT) |
commit | 030c620e9f3f4e86b77a69e77a604a0c1e946229 (patch) | |
tree | 3ba2e13a260feffd3f7aa2220fc9039e878da790 | |
parent | 63d50974f104f3626fee13c24251b91a6b3d046b (diff) | |
download | Qt-030c620e9f3f4e86b77a69e77a604a0c1e946229.zip Qt-030c620e9f3f4e86b77a69e77a604a0c1e946229.tar.gz Qt-030c620e9f3f4e86b77a69e77a604a0c1e946229.tar.bz2 |
Improved QTest::qWaitForWindowShown on X11.
The function is supposed to wait until the window has been managed by the
window manager on X11 - i.e. it has been reparented to a frame, mapped and
received at least one Expose event after that.
Reviewed-by: Olivier Goffart
-rw-r--r-- | src/gui/kernel/qwidget_x11.cpp | 75 |
1 files changed, 45 insertions, 30 deletions
diff --git a/src/gui/kernel/qwidget_x11.cpp b/src/gui/kernel/qwidget_x11.cpp index 4684bc1..007de7f 100644 --- a/src/gui/kernel/qwidget_x11.cpp +++ b/src/gui/kernel/qwidget_x11.cpp @@ -346,11 +346,6 @@ Q_GUI_EXPORT void qt_x11_enforce_cursor(QWidget * w) 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,58 @@ Q_GUI_EXPORT void qt_x11_wait_for_window_manager(QWidget* w) 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 - } - } + // first deliver events that are already in the local queue + QApplication::sendPostedEvents(); - while (!XCheckTypedWindowEvent(X11->display, w->effectiveWinId(), MapNotify, &ev)) { - if (t.elapsed() > maximumWaitTime) - return; - qApp->syncX(); // non-busy wait - } + // the normal sequence is: + // ... ConfigureNotify ... ReparentNotify ... MapNotify ... Expose + // with X11BypassWindowManagerHint: + // ConfigureNotify ... MapNotify ... Expose - qApp->x11ProcessEvent(&ev); + enum State { + Initial, Reparented, Mapped + } state = Initial; - // 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)) { + 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) + state = Mapped; + break; + case Mapped: + if (ev.type == Expose) + return; + break; + } + } else { + switch (state) { + case Initial: + if (ev.type == ReparentNotify) + state = Reparented; + break; + case Reparented: + if (ev.type == MapNotify) + state = Mapped; + break; + case Mapped: + if (ev.type == Expose) + 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) |