summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorGabriel de Dietrich <gabriel.dietrich-de@nokia.com>2010-02-09 08:56:25 (GMT)
committerGabriel de Dietrich <gabriel.dietrich-de@nokia.com>2010-02-10 08:57:17 (GMT)
commitb7af368e86874d71ffc9071c9ef009814d6a3467 (patch)
tree34bc36dbbde9fcdb20ab04a7b68b77c9f7077223 /tests
parent6f155d010b6dd5ae3c04e62b3a29f8c0ed9f0a36 (diff)
downloadQt-b7af368e86874d71ffc9071c9ef009814d6a3467.zip
Qt-b7af368e86874d71ffc9071c9ef009814d6a3467.tar.gz
Qt-b7af368e86874d71ffc9071c9ef009814d6a3467.tar.bz2
Crash when deleting the parent of a context menu while it is being displayed
Asynchronous deletion of a widget (e.g. calling deleteLater() after a timeout) could be caught by the context menu's event loop if called with exec() instead of popup(). This causes the context menu to be deleted twice in some cases, and a crash generally follows. Although this introduces a minor behaviour change, we now use popup() with the WA_DeleteOnClose attribute to display the context menu in all the contextMenuEvent() bodies, except in those where the menu was already protected by a QPointer. In QDialog::contextMenuEvent(), we use QWeakPointer to reflect the fact that the menu was previously allocated in the stack. QAbstractSpinBox, QDialog and QMdiSubWindow keep using QMenu::exec() in contextMenuEvent() as they need the QAction returned. Some auto-tests included. Reviewed-by: Olivier Task-number: QTBUG-7902
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/qlabel/tst_qlabel.cpp24
-rw-r--r--tests/auto/qlineedit/tst_qlineedit.cpp23
-rw-r--r--tests/auto/qtextedit/tst_qtextedit.cpp22
3 files changed, 69 insertions, 0 deletions
diff --git a/tests/auto/qlabel/tst_qlabel.cpp b/tests/auto/qlabel/tst_qlabel.cpp
index 7099917..153149e7 100644
--- a/tests/auto/qlabel/tst_qlabel.cpp
+++ b/tests/auto/qlabel/tst_qlabel.cpp
@@ -121,6 +121,10 @@ private slots:
void mnemonic();
void selection();
+#ifndef QT_NO_CONTEXTMENU
+ void taskQTBUG_7902_contextMenuCrash();
+#endif
+
private:
QLabel *testWidget;
QPointer<Widget> test_box;
@@ -582,5 +586,25 @@ void tst_QLabel::selection()
QCOMPARE(label.selectionStart(), 6);
}
+#ifndef QT_NO_CONTEXTMENU
+void tst_QLabel::taskQTBUG_7902_contextMenuCrash()
+{
+ QLabel *w = new QLabel("Test or crash?");
+ w->setTextInteractionFlags(Qt::TextSelectableByMouse);
+ w->show();
+ QTest::qWaitForWindowShown(w);
+
+ QTimer ti;
+ w->connect(&ti, SIGNAL(timeout()), w, SLOT(deleteLater()));
+ ti.start(300);
+
+ QContextMenuEvent *cme = new QContextMenuEvent(QContextMenuEvent::Mouse, w->rect().center());
+ qApp->postEvent(w, cme);
+
+ QTest::qWait(350);
+ // No crash, it's allright.
+}
+#endif
+
QTEST_MAIN(tst_QLabel)
#include "tst_qlabel.moc"
diff --git a/tests/auto/qlineedit/tst_qlineedit.cpp b/tests/auto/qlineedit/tst_qlineedit.cpp
index 7283916..fcca58a 100644
--- a/tests/auto/qlineedit/tst_qlineedit.cpp
+++ b/tests/auto/qlineedit/tst_qlineedit.cpp
@@ -271,6 +271,9 @@ private slots:
void taskQTBUG_4401_enterKeyClearsPassword();
void taskQTBUG_4679_moveToStartEndOfBlock();
void taskQTBUG_4679_selectToStartEndOfBlock();
+#ifndef QT_NO_CONTEXTMENU
+ void taskQTBUG_7902_contextMenuCrash();
+#endif
protected slots:
#ifdef QT3_SUPPORT
@@ -3638,5 +3641,25 @@ void tst_QLineEdit::taskQTBUG_4679_selectToStartEndOfBlock()
#endif // Q_OS_MAC
}
+#ifndef QT_NO_CONTEXTMENU
+void tst_QLineEdit::taskQTBUG_7902_contextMenuCrash()
+{
+ // Would pass before the associated commit, but left as a guard.
+ QLineEdit *w = new QLineEdit;
+ w->show();
+ QTest::qWaitForWindowShown(w);
+
+ QTimer ti;
+ w->connect(&ti, SIGNAL(timeout()), w, SLOT(deleteLater()));
+ ti.start(200);
+
+ QContextMenuEvent *cme = new QContextMenuEvent(QContextMenuEvent::Mouse, w->rect().center());
+ qApp->postEvent(w, cme);
+
+ QTest::qWait(300);
+ // No crash, it's allright.
+}
+#endif
+
QTEST_MAIN(tst_QLineEdit)
#include "tst_qlineedit.moc"
diff --git a/tests/auto/qtextedit/tst_qtextedit.cpp b/tests/auto/qtextedit/tst_qtextedit.cpp
index deb9379..101baa5 100644
--- a/tests/auto/qtextedit/tst_qtextedit.cpp
+++ b/tests/auto/qtextedit/tst_qtextedit.cpp
@@ -201,6 +201,9 @@ private slots:
void noWrapBackgrounds();
void preserveCharFormatAfterUnchangingSetPosition();
void twoSameInputMethodEvents();
+#ifndef QT_NO_CONTEXTMENU
+ void taskQTBUG_7902_contextMenuCrash();
+#endif
private:
void createSelection();
@@ -2202,5 +2205,24 @@ void tst_QTextEdit::twoSameInputMethodEvents()
QCOMPARE(ed->document()->firstBlock().layout()->lineCount(), 1);
}
+#ifndef QT_NO_CONTEXTMENU
+void tst_QTextEdit::taskQTBUG_7902_contextMenuCrash()
+{
+ QTextEdit *w = new QTextEdit;
+ w->show();
+ QTest::qWaitForWindowShown(w);
+
+ QTimer ti;
+ w->connect(&ti, SIGNAL(timeout()), w, SLOT(deleteLater()));
+ ti.start(200);
+
+ QContextMenuEvent *cme = new QContextMenuEvent(QContextMenuEvent::Mouse, w->rect().center());
+ qApp->postEvent(w->viewport(), cme);
+
+ QTest::qWait(300);
+ // No crash, it's allright.
+}
+#endif
+
QTEST_MAIN(tst_QTextEdit)
#include "tst_qtextedit.moc"