summaryrefslogtreecommitdiffstats
path: root/tests/auto/widgets/widgets
diff options
context:
space:
mode:
authorVolker Hilsheimer <volker.hilsheimer@qt.io>2021-10-24 14:31:33 +0200
committerVolker Hilsheimer <volker.hilsheimer@qt.io>2021-11-05 16:54:55 +0100
commit02164b292f002b051f34a88871145415fad94f32 (patch)
tree8e94447ef374b1fba3774455009d998ce496e270 /tests/auto/widgets/widgets
parentc5409964b0c627b25131c73f95794314feb51b5d (diff)
Don't use QCursor::pos in QTabBar and fix hover handling
Relying on QCursor::pos makes tests fragile and prevents multi-seat support. Instead, record the mouse position in the already existing event handling, and use that instead. Styles might use either WA_Hover or enable mouse tracking for the widget to enable hover-effects, so we need to support both. Fix the scenario where a newly inserted tab ends up under the mouse, which was previously not handled correctly (only the case of removing a tab was). Clean up the repaint management when the hovered tab changes; just call update on the old rect, and then later update on the new rect; there's no need to make a copy first, updates are posted and compressed. Add a unit test that makes sure that we paint tabs that should be under the mouse in the hovered state. Since not all styles enable hovering and/or mouse tracking in all cases, use a style sheet for those styles that don't. Change-Id: I7cdbb18e9e04b52651e273680fec87b50cb81e05 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io> Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
Diffstat (limited to 'tests/auto/widgets/widgets')
-rw-r--r--tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp84
1 files changed, 84 insertions, 0 deletions
diff --git a/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp b/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp
index 9fa85ee8e5..41f1cb5e64 100644
--- a/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp
+++ b/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp
@@ -107,6 +107,9 @@ private slots:
void currentTabLargeFont();
+ void hoverTab_data();
+ void hoverTab();
+
private:
void checkPositions(const TabBar &tabbar, const QList<int> &positions);
};
@@ -1033,5 +1036,86 @@ void tst_QTabBar::currentTabLargeFont()
QVERIFY(oldTabRects != newTabRects);
}
+void tst_QTabBar::hoverTab_data()
+{
+ // Since we still rely on moving the mouse via QCursor::setPos in QTest::mouseMove,
+ // skip this test if we can't
+ const QPoint cursorPos = QCursor::pos() + QPoint(10, 10);
+ QCursor::setPos(cursorPos);
+ if (!QTest::qWaitFor([cursorPos]{ return QCursor::pos() == cursorPos; }, 500))
+ QSKIP("Can't move mouse");
+
+ QTest::addColumn<bool>("documentMode");
+ QTest::addRow("normal mode") << true;
+ QTest::addRow("document mode") << true;
+}
+
+void tst_QTabBar::hoverTab()
+{
+ QFETCH(bool, documentMode);
+ QWidget window;
+ class TabBar : public QTabBar
+ {
+ public:
+ using QTabBar::QTabBar;
+ void initStyleOption(QStyleOptionTab *option, int tabIndex) const override
+ {
+ QTabBar::initStyleOption(option, tabIndex);
+ styleOptions[tabIndex] = *option;
+ }
+ mutable QHash<int, QStyleOptionTab> styleOptions;
+ } tabbar(&window);
+
+ tabbar.setDocumentMode(documentMode);
+ tabbar.addTab("A");
+ tabbar.addTab("B");
+ tabbar.addTab("C");
+ tabbar.addTab("D");
+
+ tabbar.move(0,0);
+ window.setMinimumSize(tabbar.sizeHint());
+ tabbar.ensurePolished();
+
+ // some styles set those flags, some don't. If not, use a style sheet
+ if (!(tabbar.testAttribute(Qt::WA_Hover) || tabbar.hasMouseTracking())) {
+ tabbar.setStyleSheet(R"(
+ QTabBar::tab { background: blue; }
+ QTabBar::tab::hover { background: yellow; }
+ QTabBar::tab::selected { background: red; }
+ )");
+ }
+
+ window.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&window));
+
+ QTest::mouseMove(&tabbar, tabbar.tabRect(0).center());
+ QTRY_VERIFY(tabbar.styleOptions[0].state & QStyle::State_Selected);
+ QTRY_COMPARE(tabbar.styleOptions[1].state & QStyle::State_MouseOver, QStyle::State_None);
+ QTRY_COMPARE(tabbar.styleOptions[2].state & QStyle::State_MouseOver, QStyle::State_None);
+ QTRY_COMPARE(tabbar.styleOptions[3].state & QStyle::State_MouseOver, QStyle::State_None);
+
+ QTest::mouseMove(&tabbar, tabbar.tabRect(1).center());
+ QTRY_COMPARE(tabbar.styleOptions[1].state & QStyle::State_MouseOver, QStyle::State_MouseOver);
+ QCOMPARE(tabbar.styleOptions[2].state & QStyle::State_MouseOver, QStyle::State_None);
+ QCOMPARE(tabbar.styleOptions[3].state & QStyle::State_MouseOver, QStyle::State_None);
+
+ QTest::mouseMove(&tabbar, tabbar.tabRect(2).center());
+ QTRY_COMPARE(tabbar.styleOptions[2].state & QStyle::State_MouseOver, QStyle::State_MouseOver);
+ QCOMPARE(tabbar.styleOptions[1].state & QStyle::State_MouseOver, QStyle::State_None);
+ QCOMPARE(tabbar.styleOptions[3].state & QStyle::State_MouseOver, QStyle::State_None);
+
+ // removing tab 2 lays the tabs out so that they stretch across the
+ // tab bar; tab 1 is now where the cursor was. What matters is that a
+ // different tab is now hovered (rather than none).
+ tabbar.removeTab(2);
+ QTRY_COMPARE(tabbar.styleOptions[1].state & QStyle::State_MouseOver, QStyle::State_MouseOver);
+ QCOMPARE(tabbar.styleOptions[2].state & QStyle::State_MouseOver, QStyle::State_None);
+
+ // inserting a tab at index 2 again should paint the new tab hovered
+ tabbar.insertTab(2, "C2");
+ QTRY_COMPARE(tabbar.styleOptions[2].state & QStyle::State_MouseOver, QStyle::State_MouseOver);
+ QCOMPARE(tabbar.styleOptions[1].state & QStyle::State_MouseOver, QStyle::State_None);
+}
+
QTEST_MAIN(tst_QTabBar)
#include "tst_qtabbar.moc"