summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDenis Dzyubenko <denis.dzyubenko@nokia.com>2010-02-04 12:30:13 (GMT)
committerDenis Dzyubenko <denis.dzyubenko@nokia.com>2010-02-04 15:04:54 (GMT)
commit030c620e9f3f4e86b77a69e77a604a0c1e946229 (patch)
tree3ba2e13a260feffd3f7aa2220fc9039e878da790
parent63d50974f104f3626fee13c24251b91a6b3d046b (diff)
downloadQt-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.cpp75
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)