From a6d34dc0c8715c461fa47da76f5615df60f7b61a Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Thu, 17 Sep 2009 13:18:42 +0200 Subject: 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 --- src/gui/kernel/qwidget_x11.cpp | 37 ++++++++++++++++++++++++++++++------- 1 file 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) -- cgit v0.12