{
public:
ColorWidget(QWidget *parent = 0, const QColor &c = QColor(Qt::red))
- : QWidget(parent, Qt::FramelessWindowHint), color(c)
+ : QWidget(parent, Qt::FramelessWindowHint), color(c), enters(0), leaves(0)
{
QPalette opaquePalette = palette();
opaquePalette.setColor(backgroundRole(), color);
r = QRegion();
}
+ void enterEvent(QEvent *) { ++enters; }
+ void leaveEvent(QEvent *) { ++leaves; }
+
+ void resetCounts()
+ {
+ enters = 0;
+ leaves = 0;
+ }
+
QColor color;
QRegion r;
+ int enters;
+ int leaves;
};
#define VERIFY_COLOR(region, color) { \
// Move the mouse cursor to a safe location
QCursor::setPos(0,0);
- QWidget topLevelWidget;
- QLineEdit childWidget1(&topLevelWidget);
- QLineEdit childWidget2(&topLevelWidget);
- QWidget popupWidget(0, Qt::Popup);
+ ColorWidget topLevelWidget(0, Qt::blue);
+ ColorWidget childWidget1(&topLevelWidget, Qt::yellow);
+ ColorWidget childWidget2(&topLevelWidget, Qt::black);
+ ColorWidget popupWidget(0, Qt::green);
topLevelWidget.setObjectName("topLevelWidget");
childWidget1.setObjectName("childWidget1");
childWidget2.setObjectName("childWidget2");
popupWidget.setObjectName("popupWidget");
+ popupWidget.setWindowFlags(Qt::Popup);
+
topLevelWidget.setGeometry(100, 100, 300, 300);
childWidget1.setGeometry(20, 20, 100, 100);
childWidget2.setGeometry(20, 120, 100, 100);
QPoint outsideWindowPoint(30, -10);
QPoint inWindowPoint(30, 10);
QPoint child1Point(30, 50);
- QPoint child2Point(30, 150);
+ QPoint child2PointA(30, 150);
+ QPoint child2PointB(31, 151);
// Outside window
QTest::mouseMove(window, outsideWindowPoint);
QVERIFY(!childWidget2.underMouse());
// In childWidget2
- QTest::mouseMove(window, child2Point);
+ QTest::mouseMove(window, child2PointA);
QVERIFY(topLevelWidget.underMouse());
QVERIFY(!childWidget1.underMouse());
QVERIFY(childWidget2.underMouse());
+ topLevelWidget.resetCounts();
+ childWidget1.resetCounts();
+ childWidget2.resetCounts();
+ popupWidget.resetCounts();
+
// Throw up a popup window
popupWidget.show();
QVERIFY(QTest::qWaitForWindowExposed(&popupWidget));
QVERIFY(popupWindow);
QVERIFY(QApplication::activePopupWidget() == &popupWidget);
- // If there is an active popup, undermouse should not be reported (QTBUG-27478)
+ // If there is an active popup, undermouse should not be reported (QTBUG-27478),
+ // but opening a popup causes leave for widgets under mouse.
QVERIFY(!topLevelWidget.underMouse());
QVERIFY(!childWidget1.underMouse());
QVERIFY(!childWidget2.underMouse());
+ QVERIFY(!popupWidget.underMouse());
+ QCOMPARE(popupWidget.enters, 0);
+ QCOMPARE(popupWidget.leaves, 0);
+ QCOMPARE(topLevelWidget.enters, 0);
+ QCOMPARE(topLevelWidget.leaves, 1);
+ QCOMPARE(childWidget1.enters, 0);
+ QCOMPARE(childWidget1.leaves, 0);
+ QCOMPARE(childWidget2.enters, 0);
+ QCOMPARE(childWidget2.leaves, 1);
+ topLevelWidget.resetCounts();
+ childWidget2.resetCounts();
+
+ // Note about commented out compares below:
+ // Widgets are not receiving enter/leave events properly when there is a popup up,
+ // so all enter and leave counts are not correct yet.
+ // Fix this test when QTBUG-27800 is fixed (i.e. uncomment commented out compares).
+
+ // Moving around while popup active should not change undermouse either,
+ // but should send enter and leave events for widgets
+ QTest::mouseMove(popupWindow, popupWindow->mapFromGlobal(window->mapToGlobal(child2PointB)));
+ QVERIFY(!topLevelWidget.underMouse());
+ QVERIFY(!childWidget1.underMouse());
+ QVERIFY(!childWidget2.underMouse());
+ QVERIFY(!popupWidget.underMouse());
+ QCOMPARE(popupWidget.enters, 0);
+ QCOMPARE(popupWidget.leaves, 0);
+ //QCOMPARE(topLevelWidget.enters, 1); // QTBUG-27800
+ QCOMPARE(topLevelWidget.leaves, 0);
+ QCOMPARE(childWidget1.enters, 0);
+ QCOMPARE(childWidget1.leaves, 0);
+ //QCOMPARE(childWidget2.enters, 1); // QTBUG-27800
+ QCOMPARE(childWidget2.leaves, 0);
+ topLevelWidget.resetCounts();
+ childWidget2.resetCounts();
- // Moving around while popup active should not change undermouse either
QTest::mouseMove(popupWindow, popupWindow->mapFromGlobal(window->mapToGlobal(inWindowPoint)));
QVERIFY(!topLevelWidget.underMouse());
QVERIFY(!childWidget1.underMouse());
QVERIFY(!childWidget2.underMouse());
+ QVERIFY(!popupWidget.underMouse());
+ QCOMPARE(popupWidget.enters, 0);
+ QCOMPARE(popupWidget.leaves, 0);
+ QCOMPARE(topLevelWidget.enters, 0);
+ QCOMPARE(topLevelWidget.leaves, 0);
+ QCOMPARE(childWidget1.enters, 0);
+ QCOMPARE(childWidget1.leaves, 0);
+ QCOMPARE(childWidget2.enters, 0);
+ //QCOMPARE(childWidget2.leaves, 1); // QTBUG-27800
+ childWidget2.resetCounts();
QTest::mouseMove(popupWindow, popupWindow->mapFromGlobal(window->mapToGlobal(child1Point)));
QVERIFY(!topLevelWidget.underMouse());
QVERIFY(!childWidget1.underMouse());
QVERIFY(!childWidget2.underMouse());
+ QVERIFY(!popupWidget.underMouse());
+ QCOMPARE(popupWidget.enters, 0);
+ QCOMPARE(popupWidget.leaves, 0);
+ QCOMPARE(topLevelWidget.enters, 0);
+ QCOMPARE(topLevelWidget.leaves, 0);
+ //QCOMPARE(childWidget1.enters, 1); // QTBUG-27800
+ QCOMPARE(childWidget1.leaves, 0);
+ QCOMPARE(childWidget2.enters, 0);
+ QCOMPARE(childWidget2.leaves, 0);
+ childWidget1.resetCounts();
+
+ // Mouse moves off-application, should cause leaves for currently entered widgets
+ QWindowSystemInterface::handleLeaveEvent(window);
+ QApplication::processEvents();
+ QVERIFY(!topLevelWidget.underMouse());
+ QVERIFY(!childWidget1.underMouse());
+ QVERIFY(!childWidget2.underMouse());
+ QVERIFY(!popupWidget.underMouse());
+ QCOMPARE(popupWidget.enters, 0);
+ QCOMPARE(popupWidget.leaves, 0);
+ QCOMPARE(topLevelWidget.enters, 0);
+ QCOMPARE(topLevelWidget.leaves, 1);
+ QCOMPARE(childWidget1.enters, 0);
+ //QCOMPARE(childWidget1.leaves, 1); // QTBUG-27800
+ QCOMPARE(childWidget2.enters, 0);
+ QCOMPARE(childWidget2.leaves, 0);
+ topLevelWidget.resetCounts();
+ childWidget1.resetCounts();
+
+ // Mouse enters back in, should cause enter to topLevelWidget
+ QWindowSystemInterface::handleEnterEvent(window);
+ QApplication::processEvents();
+ QVERIFY(!topLevelWidget.underMouse());
+ QVERIFY(!childWidget1.underMouse());
+ QVERIFY(!childWidget2.underMouse());
+ QVERIFY(!popupWidget.underMouse());
+ QCOMPARE(popupWidget.enters, 0);
+ QCOMPARE(popupWidget.leaves, 0);
+ QCOMPARE(topLevelWidget.enters, 1);
+ QCOMPARE(topLevelWidget.leaves, 0);
+ QCOMPARE(childWidget1.enters, 0);
+ QCOMPARE(childWidget1.leaves, 0);
+ QCOMPARE(childWidget2.enters, 0);
+ QCOMPARE(childWidget2.leaves, 0);
+ topLevelWidget.resetCounts();
+
+ // Mouse moves to child widget, should cause enter to child
+ QTest::mouseMove(popupWindow, popupWindow->mapFromGlobal(window->mapToGlobal(child2PointB)));
+ QVERIFY(!topLevelWidget.underMouse());
+ QVERIFY(!childWidget1.underMouse());
+ QVERIFY(!childWidget2.underMouse());
+ QVERIFY(!popupWidget.underMouse());
+ QCOMPARE(popupWidget.enters, 0);
+ QCOMPARE(popupWidget.leaves, 0);
+ QCOMPARE(topLevelWidget.enters, 0);
+ QCOMPARE(topLevelWidget.leaves, 0);
+ QCOMPARE(childWidget1.enters, 0);
+ QCOMPARE(childWidget1.leaves, 0);
+ //QCOMPARE(childWidget2.enters, 1); // QTBUG-27800
+ QCOMPARE(childWidget2.leaves, 0);
+ childWidget2.resetCounts();
+
+ // Mouse enters popup, should cause enter to popup and leave to current widgets under mouse
+ QWindowSystemInterface::handleLeaveEvent(window);
+ QWindowSystemInterface::handleEnterEvent(popupWindow);
+ QApplication::processEvents();
+ QVERIFY(!topLevelWidget.underMouse());
+ QVERIFY(!childWidget1.underMouse());
+ QVERIFY(!childWidget2.underMouse());
+ QVERIFY(popupWidget.underMouse());
+ QCOMPARE(popupWidget.enters, 1);
+ QCOMPARE(popupWidget.leaves, 0);
+ QCOMPARE(topLevelWidget.enters, 0);
+ QCOMPARE(topLevelWidget.leaves, 1);
+ QCOMPARE(childWidget1.enters, 0);
+ QCOMPARE(childWidget1.leaves, 0);
+ QCOMPARE(childWidget2.enters, 0);
+ //QCOMPARE(childWidget2.leaves, 1); // QTBUG-27800
+ popupWidget.resetCounts();
+ topLevelWidget.resetCounts();
+ childWidget2.resetCounts();
+
+ // Mouse moves around inside popup, no changes
+ QTest::mouseMove(popupWindow, QPoint(5, 5));
+ QVERIFY(!topLevelWidget.underMouse());
+ QVERIFY(!childWidget1.underMouse());
+ QVERIFY(!childWidget2.underMouse());
+ QVERIFY(popupWidget.underMouse());
+ QCOMPARE(popupWidget.enters, 0);
+ QCOMPARE(popupWidget.leaves, 0);
+ QCOMPARE(topLevelWidget.enters, 0);
+ QCOMPARE(topLevelWidget.leaves, 0);
+ QCOMPARE(childWidget1.enters, 0);
+ QCOMPARE(childWidget1.leaves, 0);
+ QCOMPARE(childWidget2.enters, 0);
+ QCOMPARE(childWidget2.leaves, 0);
+
+ // Mouse leaves popup and enters topLevelWidget, should cause enter to topLevelWidget and leave for popup
+ QWindowSystemInterface::handleLeaveEvent(popupWindow);
+ QWindowSystemInterface::handleEnterEvent(window);
+ QApplication::processEvents();
+ QVERIFY(!topLevelWidget.underMouse());
+ QVERIFY(!childWidget1.underMouse());
+ QVERIFY(!childWidget2.underMouse());
+ QVERIFY(!popupWidget.underMouse());
+ QCOMPARE(popupWidget.enters, 0);
+ QCOMPARE(popupWidget.leaves, 1);
+ QCOMPARE(topLevelWidget.enters, 1);
+ QCOMPARE(topLevelWidget.leaves, 0);
+ QCOMPARE(childWidget1.enters, 0);
+ QCOMPARE(childWidget1.leaves, 0);
+ QCOMPARE(childWidget2.enters, 0);
+ QCOMPARE(childWidget2.leaves, 0);
}
#endif // QTEST_NO_CURSOR