diff options
author | Denis Dzyubenko <denis.dzyubenko@nokia.com> | 2009-09-17 11:18:42 (GMT) |
---|---|---|
committer | Denis Dzyubenko <denis.dzyubenko@nokia.com> | 2009-09-18 12:54:52 (GMT) |
commit | a6d34dc0c8715c461fa47da76f5615df60f7b61a (patch) | |
tree | 3b526c9a4b1777655b6f2b026cb3ac60e6d81b99 /src/gui | |
parent | 22b350f9916947ead9c0db6d942ac5ba03ea4ca8 (diff) | |
download | Qt-a6d34dc0c8715c461fa47da76f5615df60f7b61a.zip Qt-a6d34dc0c8715c461fa47da76f5615df60f7b61a.tar.gz Qt-a6d34dc0c8715c461fa47da76f5615df60f7b61a.tar.bz2 |
Improved a qt_x11_wait_for_window_manager.
In addition to waiting until the window manager maps and reparents the
window, also wait until we get initial expose event.
The window manager will most probably send us several ConfigureNotify
events, so wait until all of them are handled in addition to the Expose
event (as one might rely on another).
Also, we shouldn't wait for the ReparentNotify event if the window has
X11BypassWindowManagerHint.
Reviewed-by: Olivier Goffart
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/kernel/qwidget_x11.cpp | 37 |
1 files changed, 30 insertions, 7 deletions
diff --git a/src/gui/kernel/qwidget_x11.cpp b/src/gui/kernel/qwidget_x11.cpp index 58fb3e8d..283dfb2 100644 --- a/src/gui/kernel/qwidget_x11.cpp +++ b/src/gui/kernel/qwidget_x11.cpp @@ -346,6 +346,10 @@ 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) { @@ -355,23 +359,42 @@ Q_GUI_EXPORT void qt_x11_wait_for_window_manager(QWidget* w) XEvent ev; QTime t; t.start(); + static const int maximumWaitTime = 2000; if (!w->testAttribute(Qt::WA_WState_Created)) return; - while (!XCheckTypedWindowEvent(X11->display, w->effectiveWinId(), ReparentNotify, &ev)) { - if (t.elapsed() > 2000) - return; - qApp->syncX(); // non-busy wait + + 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() > 2000) + if (t.elapsed() > maximumWaitTime) return; qApp->syncX(); // non-busy wait } qApp->x11ProcessEvent(&ev); - if (XCheckTypedWindowEvent(X11->display, w->effectiveWinId(), ConfigureNotify, &ev)) - 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)) { + qApp->x11ProcessEvent(&ev); + if (ev.type == Expose) + return; + } + if (t.elapsed() > maximumWaitTime) + return; + qApp->syncX(); // non-busy wait + } } void qt_change_net_wm_state(const QWidget* w, bool set, Atom one, Atom two = 0) |