summaryrefslogtreecommitdiffstats
path: root/tests/auto/widgets
diff options
context:
space:
mode:
authorBłażej Szczygieł <spaz16@wp.pl>2016-01-21 13:19:37 +0100
committerShawn Rutledge <shawn.rutledge@theqtcompany.com>2016-02-24 04:33:36 +0000
commit57ecd5aeeb1f609206933be66b92fcdf703703d7 (patch)
tree158a491f8fab6563c8990e35af2bdd35d74c6976 /tests/auto/widgets
parenteadd7e9cfb4e0802aa9da63badc41c39fec219bb (diff)
QtWidgets: Proper delivery of enter/leave event to context menus
First-level context menu grabs the mouse, so all mouse events are delivered to it. This menu passes the mouse events to submenus. Any platform delivers mouse enter/leave event differently when window is grabbed. This patch unifies event delivery to context menus - it can block some unwanted events and it emulates fake events if necessary. This patch can reduce duplicated events and can provide proper enter or leave event to additional widgets in the context menu. It can also prevent submenu from unwanted close on Windows and X11. Added autotest. Task-number: QTBUG-45565 Task-number: QTBUG-45893 Task-number: QTBUG-47515 Change-Id: I7dd476d0be23afa34e947e54aef235012d173dcf Reviewed-by: Shawn Rutledge <shawn.rutledge@theqtcompany.com>
Diffstat (limited to 'tests/auto/widgets')
-rw-r--r--tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp109
1 files changed, 109 insertions, 0 deletions
diff --git a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp
index b3f9c54f24..20f17f6e9e 100644
--- a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp
+++ b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp
@@ -110,6 +110,9 @@ private slots:
void QTBUG7411_submenus_activate();
void QTBUG30595_rtl_submenu();
void QTBUG20403_nested_popup_on_shortcut_trigger();
+#ifndef QT_NO_CURSOR
+ void QTBUG47515_widgetActionEnterLeave();
+#endif
void QTBUG_10735_crashWithDialog();
#ifdef Q_OS_MAC
void QTBUG_37933_ampersands_data();
@@ -1070,6 +1073,112 @@ void tst_QMenu::QTBUG20403_nested_popup_on_shortcut_trigger()
QVERIFY(!subsub1.isVisible());
}
+class MyWidget : public QWidget
+{
+public:
+ MyWidget(QWidget *parent) :
+ QWidget(parent),
+ move(0), enter(0), leave(0)
+ {
+ setMinimumSize(100, 100);
+ setMouseTracking(true);
+ }
+
+ bool event(QEvent *e) Q_DECL_OVERRIDE
+ {
+ switch (e->type()) {
+ case QEvent::MouseMove:
+ ++move;
+ break;
+ case QEvent::Enter:
+ ++enter;
+ break;
+ case QEvent::Leave:
+ ++leave;
+ break;
+ default:
+ break;
+ }
+ return QWidget::event(e);
+ }
+
+ int move, enter, leave;
+};
+
+#ifndef QT_NO_CURSOR
+void tst_QMenu::QTBUG47515_widgetActionEnterLeave()
+{
+ if (QGuiApplication::platformName() == QLatin1String("cocoa"))
+ QSKIP("This test fails on OS X on CI");
+
+ const QPoint center = QGuiApplication::primaryScreen()->availableGeometry().center();
+ const QPoint cursorPos = center - QPoint(100, 100);
+
+ QScopedPointer<QMenu> menu1(new QMenu("Menu1"));
+ QScopedPointer<QMenu> menu2(new QMenu("Menu2"));
+
+ QWidgetAction *wA1 = new QWidgetAction(menu1.data());
+ MyWidget *w1 = new MyWidget(menu1.data());
+ wA1->setDefaultWidget(w1);
+
+ QWidgetAction *wA2 = new QWidgetAction(menu2.data());
+ MyWidget *w2 = new MyWidget(menu2.data());
+ wA2->setDefaultWidget(w2);
+
+ QAction *nextMenuAct = menu1->addMenu(menu2.data());
+
+ menu1->addAction(wA1);
+ menu2->addAction(wA2);
+
+ // Root menu
+ {
+ QCursor::setPos(cursorPos);
+ QCoreApplication::processEvents();
+
+ menu1->popup(center);
+ QVERIFY(QTest::qWaitForWindowExposed(menu1.data()));
+
+ QCursor::setPos(w1->mapToGlobal(w1->rect().center()));
+ QVERIFY(w1->isVisible());
+ QTRY_COMPARE(w1->leave, 0);
+ QTRY_COMPARE(w1->enter, 1);
+
+ // Check whether leave event is not delivered on mouse move
+ w1->move = 0;
+ QCursor::setPos(w1->mapToGlobal(w1->rect().center()) + QPoint(1, 1));
+ QTRY_COMPARE(w1->move, 1);
+ QTRY_COMPARE(w1->leave, 0);
+ QTRY_COMPARE(w1->enter, 1);
+
+ QCursor::setPos(cursorPos);
+ QTRY_COMPARE(w1->leave, 1);
+ QTRY_COMPARE(w1->enter, 1);
+ }
+
+ // Submenu
+ {
+ menu1->setActiveAction(nextMenuAct);
+ QVERIFY(QTest::qWaitForWindowExposed(menu2.data()));
+
+ QCursor::setPos(w2->mapToGlobal(w2->rect().center()));
+ QVERIFY(w2->isVisible());
+ QTRY_COMPARE(w2->leave, 0);
+ QTRY_COMPARE(w2->enter, 1);
+
+ // Check whether leave event is not delivered on mouse move
+ w2->move = 0;
+ QCursor::setPos(w2->mapToGlobal(w2->rect().center()) + QPoint(1, 1));
+ QTRY_COMPARE(w2->move, 1);
+ QTRY_COMPARE(w2->leave, 0);
+ QTRY_COMPARE(w2->enter, 1);
+
+ QCursor::setPos(cursorPos);
+ QTRY_COMPARE(w2->leave, 1);
+ QTRY_COMPARE(w2->enter, 1);
+ }
+}
+#endif // !QT_NO_CURSOR
+
class MyMenu : public QMenu
{
Q_OBJECT