Unset _NET_WM_USER_TIME_WINDOW before destroying the window
authorJan Arne Petersen <jpetersen@openismus.com>
Fri, 24 Feb 2012 17:05:06 +0000 (18:05 +0100)
committerQt by Nokia <qt-info@nokia.com>
Thu, 1 Mar 2012 18:00:15 +0000 (19:00 +0100)
Otherwise metacity was crashing when a QWindow was destroyed immediately
after being activated, because metacity was trying to select events
(XSelectInput) for the already destroyed m_netWmUserTimeWindow.

Task-number: QTBUG-24492
Change-Id: Iedbe7bdd6b26110ca8bec6f33525209ae551ffd5
Reviewed-by: Samuel Rødal <samuel.rodal@nokia.com>
src/plugins/platforms/xcb/qxcbwindow.cpp
tests/auto/gui/kernel/qwindow/tst_qwindow.cpp

index 1688fdf..7777820 100644 (file)
@@ -369,6 +369,14 @@ void QXcbWindow::destroy()
     if (m_syncCounter && m_screen->syncRequestSupported())
         Q_XCB_CALL(xcb_sync_destroy_counter(xcb_connection(), m_syncCounter));
     if (m_window) {
+        if (m_netWmUserTimeWindow) {
+            xcb_delete_property(xcb_connection(), m_window, atom(QXcbAtom::_NET_WM_USER_TIME_WINDOW));
+            // Some window managers, like metacity, do XSelectInput on the _NET_WM_USER_TIME_WINDOW window,
+            // without trapping BadWindow (which crashes when the user time window is destroyed).
+            connection()->sync();
+            xcb_destroy_window(xcb_connection(), m_netWmUserTimeWindow);
+            m_netWmUserTimeWindow = XCB_NONE;
+        }
         connection()->removeWindow(m_window);
         Q_XCB_CALL(xcb_destroy_window(xcb_connection(), m_window));
     }
index 90c96b4..f4556f7 100644 (file)
@@ -64,6 +64,8 @@ private slots:
     void touchCancelWithTouchToMouse();
     void orientation();
     void close();
+    void activateAndClose();
+
     void initTestCase()
     {
         touchDevice = new QTouchDevice;
@@ -632,5 +634,16 @@ void tst_QWindow::close()
     QVERIFY(b.close());
 }
 
+void tst_QWindow::activateAndClose()
+{
+    for (int i = 0; i < 10; ++i)  {
+       QWindow window;
+       window.show();
+       QTest::qWaitForWindowShown(&window);
+       window.requestActivateWindow();
+       QTRY_COMPARE(qGuiApp->focusWindow(), &window);
+    }
+}
+
 #include <tst_qwindow.moc>
 QTEST_MAIN(tst_QWindow);