tests: Port some tests to QtQuick

15 to go
This commit is contained in:
Sergio Martins
2020-11-10 18:00:19 +00:00
parent 22d5db32ce
commit 1443eff1d9
2 changed files with 361 additions and 360 deletions

View File

@@ -43,6 +43,7 @@
# include <QLineEdit>
# include <QTextEdit>
# include <QTabBar>
# include <QMenuBar>
#endif
#ifdef Q_OS_WIN
@@ -223,6 +224,8 @@ private Q_SLOTS:
void tst_lastFloatingPositionIsRestored();
void tst_negativeAnchorPositionWhenEmbedded();
void tst_negativeAnchorPositionWhenEmbedded_data();
void tst_floatingAction();
void tst_raise();
#ifdef KDDOCKWIDGETS_QTWIDGETS
// TODO: Port these to QtQuick
@@ -233,6 +236,7 @@ private Q_SLOTS:
void tst_dragByTabBar();
void tst_dragBySingleTab();
void tst_mainWindowAlwaysHasCentralWidget();
void tst_dockableMainWindows();
#endif
};
@@ -5017,6 +5021,75 @@ void TestCommon::tst_mainWindowAlwaysHasCentralWidget()
delete dock->window();
}
void TestCommon::tst_dockableMainWindows()
{
EnsureTopLevelsDeleted e;
auto m1 = createMainWindow();
auto dock1 = createDockWidget("dock1", new QPushButton("foo"));
m1->addDockWidget(dock1, Location_OnTop);
auto m2 = new KDDockWidgets::MainWindow("mainwindow-dockable");
auto m2Container = createDockWidget("mainwindow-dw", m2);
auto menubar = m2->menuBar();
menubar->addMenu("File");
menubar->addMenu("View");
menubar->addMenu("Help");
m2Container->show();
auto dock21 = createDockWidget("dock21", new QPushButton("foo"));
auto dock22 = createDockWidget("dock22", new QPushButton("foo"));
m2->addDockWidget(dock21, Location_OnLeft);
m2->addDockWidget(dock22, Location_OnRight);
auto fw = m2Container->floatingWindow();
TitleBar *fwTitleBar = fw->titleBar();
QVERIFY(fw->hasSingleFrame());
QVERIFY(fw->hasSingleDockWidget());
// Check that the inner-inner dock widgets have a visible title-bar
QVERIFY(dock21->titleBar()->isVisible());
QVERIFY(dock22->titleBar()->isVisible());
QVERIFY(dock21->titleBar() != fwTitleBar);
QVERIFY(dock22->titleBar() != fwTitleBar);
QTest::qWait(10); // the DND state machine needs the event loop to start, otherwise activeState() is nullptr. (for offscreen QPA)
const QPoint startPoint = fwTitleBar->mapToGlobal(QPoint(5, 5));
const QPoint destination = startPoint + QPoint(20, 20);
// Check that we don't get the "Refusing to itself" warning. not actually dropping anywhere
drag(fwTitleBar, startPoint, destination);
// The FloatingWindow has a single DockWidget, so it shows the title bar, while the Frame doesn't
QVERIFY(fwTitleBar->isVisible());
QVERIFY(!m2Container->frame()->titleBar()->isVisible());
fw->dropArea()->addDockWidget(dock1, Location::Location_OnLeft, nullptr);
// Now the FloatingWindow has two dock widgets, so our main window dock widget also shows the title bar
QVERIFY(fwTitleBar->isVisible());
QVERIFY(m2Container->frame()->titleBar()->isVisible());
// Put it how it was, FloatingWindow is single dock again
auto frame1 = dock1->frame();
dock1->close();
Testing::waitForDeleted(frame1);
QVERIFY(fwTitleBar->isVisible());
QVERIFY(!m2Container->frame()->titleBar()->isVisible());
// Repeat, but instead of closing dock1, we float it
fw->dropArea()->addDockWidget(dock1, Location::Location_OnLeft, nullptr);
QVERIFY(fwTitleBar->isVisible());
QVERIFY(m2Container->frame()->titleBar()->isVisible());
frame1 = dock1->frame();
frame1->titleBar()->onFloatClicked();
QVERIFY(fwTitleBar->isVisible());
QVERIFY(!m2Container->frame()->titleBar()->isVisible());
fw->dropArea()->addDockWidget(dock1, Location::Location_OnLeft, nullptr);
}
#endif
void TestCommon::tst_negativeAnchorPositionWhenEmbedded_data()
@@ -5058,4 +5131,292 @@ void TestCommon::tst_negativeAnchorPositionWhenEmbedded()
delete m->window();
}
void TestCommon::tst_floatingAction()
{
// Tests DockWidget::floatAction()
EnsureTopLevelsDeleted e;
{
// 1. Create a MainWindow with two docked dock-widgets, then float the first one.
auto m = createMainWindow();
auto dock1 = createDockWidget("dock1", new QPushButton("one"));
auto dock2 = createDockWidget("dock2", new QPushButton("two"));
m->addDockWidget(dock1, KDDockWidgets::Location_OnLeft);
m->addDockWidget(dock2, KDDockWidgets::Location_OnRight);
auto action = dock1->floatAction();
QVERIFY(!dock1->isFloating());
QVERIFY(!action->isChecked());
QVERIFY(action->isEnabled());
QCOMPARE(action->toolTip(), tr("Detach"));
action->toggle();
QVERIFY(dock1->isFloating());
QVERIFY(action->isChecked());
QVERIFY(action->isEnabled());
QCOMPARE(action->toolTip(), tr("Dock"));
auto fw = dock1->floatingWindow();
QVERIFY(fw);
//2. Put it back, via setFloating(). It should return to its place.
action->toggle();
QVERIFY(!dock1->isFloating());
QVERIFY(!action->isChecked());
QVERIFY(action->isEnabled());
QVERIFY(!dock1->isTabbed());
QCOMPARE(action->toolTip(), tr("Detach"));;
Testing::waitForDeleted(fw);
}
{
// 1. Create a MainWindow with one docked dock-widgets, and one floating.
auto m = createMainWindow();
auto dock1 = createDockWidget("dock1", new QPushButton("one"));
auto dock2 = createDockWidget("dock2", new QPushButton("two"));
m->addDockWidget(dock1, KDDockWidgets::Location_OnLeft);
//The floating window action should be disabled as it has no previous place
auto action = dock2->floatAction();
QVERIFY(dock2->isFloating());
QVERIFY(action->isChecked());
QVERIFY(!action->isEnabled());
QCOMPARE(action->toolTip(), tr("Dock"));
m->addDockWidget(dock2, KDDockWidgets::Location_OnRight);
QVERIFY(!dock2->isFloating());
QVERIFY(!action->isChecked());
QVERIFY(action->isEnabled());
QCOMPARE(action->toolTip(), tr("Detach"));
action->toggle();
QVERIFY(dock2->isFloating());
QVERIFY(action->isChecked());
QVERIFY(action->isEnabled());
QCOMPARE(action->toolTip(), tr("Dock"));
auto fw = dock2->floatingWindow();
QVERIFY(fw);
//2. Put it back, via setFloating(). It should return to its place.
action->toggle();
QVERIFY(!dock1->isFloating());
QVERIFY(!action->isChecked());
QVERIFY(action->isEnabled());
QVERIFY(!dock1->isTabbed());
QCOMPARE(action->toolTip(), tr("Detach"));
Testing::waitForDeleted(fw);
}
{
// 3. A floating window with two tabs
auto dock1 = createDockWidget("dock1", new QPushButton("one"));
auto dock2 = createDockWidget("dock2", new QPushButton("two"));
bool dock1IsFloating = dock1->floatAction()->isChecked();
bool dock2IsFloating = dock2->floatAction()->isChecked();
connect(dock1->floatAction(), &QAction::toggled, [&dock1IsFloating] (bool t) {
Q_ASSERT(dock1IsFloating != t);
dock1IsFloating = t;
});
connect(dock2->floatAction(), &QAction::toggled, [&dock2IsFloating] (bool t) {
Q_ASSERT(dock2IsFloating != t);
dock2IsFloating = t;
});
auto fw2 = dock2->floatingWindow();
QVERIFY(dock1->isFloating());
QVERIFY(dock2->isFloating());
QVERIFY(dock1->floatAction()->isChecked());
QVERIFY(dock2->floatAction()->isChecked());
dock1->addDockWidgetAsTab(dock2);
QVERIFY(!dock1->isFloating());
QVERIFY(!dock2->isFloating());
QVERIFY(!dock1->floatAction()->isChecked());
QVERIFY(!dock2->floatAction()->isChecked());
dock2->setFloating(true);
QVERIFY(dock1->isFloating());
QVERIFY(dock1->floatAction()->isChecked());
QVERIFY(dock2->isFloating());
QVERIFY(dock2->floatAction()->isChecked());
QVERIFY(dock1IsFloating);
QVERIFY(dock2IsFloating);
delete fw2;
delete dock1->window();
delete dock2->window();
}
{
// If the dock widget is alone then it's floating, but we suddenly dock a widget side-by-side
// to it, then both aren't floating anymore. This test tests if the signal was emitted
auto dock1 = createDockWidget("one", new QPushButton("one"));
auto dock2 = createDockWidget("two", new QPushButton("two"));
QVERIFY(dock1->isFloating());
QVERIFY(dock2->isFloating());
QVERIFY(dock1->floatAction()->isChecked());
QVERIFY(dock2->floatAction()->isChecked());
auto oldFw2 = dock2->window();
QSignalSpy spy1(dock1->floatAction(), &QAction::toggled);
QSignalSpy spy2(dock2->floatAction(), &QAction::toggled);
QSignalSpy spy11(dock1, &DockWidgetBase::isFloatingChanged);
QSignalSpy spy21(dock2, &DockWidgetBase::isFloatingChanged);
dock1->addDockWidgetToContainingWindow(dock2, Location_OnRight);
QCOMPARE(spy1.count(), 1);
QCOMPARE(spy2.count(), 1);
QCOMPARE(spy11.count(), 1);
QCOMPARE(spy21.count(), 1);
QVERIFY(!dock1->isFloating());
QVERIFY(!dock2->isFloating());
QVERIFY(!dock2->floatAction()->isChecked());
QVERIFY(!dock1->floatAction()->isChecked());
delete dock1->window();
delete oldFw2->window();
}
{
// Like before, but now we use addMultiSplitter()
auto dock1 = createDockWidget("one", new QPushButton("one"));
auto dock2 = createDockWidget("two", new QPushButton("two"));
QVERIFY(dock1->isFloating());
QVERIFY(dock2->isFloating());
QVERIFY(dock1->floatAction()->isChecked());
QVERIFY(dock2->floatAction()->isChecked());
auto oldFw2 = dock2->floatingWindow();
QSignalSpy spy1(dock1->floatAction(), &QAction::toggled);
QSignalSpy spy2(dock2->floatAction(), &QAction::toggled);
QSignalSpy spy11(dock1, &DockWidgetBase::isFloatingChanged);
QSignalSpy spy21(dock2, &DockWidgetBase::isFloatingChanged);
auto dropArea1 = dock1->floatingWindow()->dropArea();
dropArea1->drop(oldFw2, Location_OnRight, nullptr);
QCOMPARE(spy1.count(), 1);
QCOMPARE(spy2.count(), 1);
QCOMPARE(spy11.count(), 1);
QCOMPARE(spy21.count(), 1);
QVERIFY(!dock1->isFloating());
QVERIFY(!dock2->isFloating());
QVERIFY(!dock2->floatAction()->isChecked());
QVERIFY(!dock1->floatAction()->isChecked());
// Let's now remove dock1, dock2 should be floating
dock1->setFloating(true);
QVERIFY(dock1->isFloating());
QVERIFY(dock2->isFloating());
QVERIFY(dock2->floatAction()->isChecked());
QVERIFY(dock1->floatAction()->isChecked());
delete dock1->window();
delete dock2->window();
delete oldFw2->window();
}
{
// Same test as before, but now tab instead of side-by-side
auto dock1 = createDockWidget("one", new QPushButton("one"));
auto dock2 = createDockWidget("two", new QPushButton("two"));
QVERIFY(dock1->isFloating());
QVERIFY(dock2->isFloating());
QVERIFY(dock1->floatAction()->isChecked());
QVERIFY(dock2->floatAction()->isChecked());
auto oldFw2 = dock2->window();
QSignalSpy spy1(dock1->floatAction(), &QAction::toggled);
QSignalSpy spy2(dock2->floatAction(), &QAction::toggled);
QSignalSpy spy11(dock1, &DockWidgetBase::isFloatingChanged);
QSignalSpy spy21(dock2, &DockWidgetBase::isFloatingChanged);
dock1->addDockWidgetAsTab(dock2);
QCOMPARE(spy1.count(), 1);
// On earlier Qt versions this is flaky, but technically correct.
// Windows can get hidden while being reparented and floating changes momentarily.
QVERIFY(spy2.count() == 1 || spy2.count() == 3);
QVERIFY(spy21.count() == 1 || spy21.count() == 3);
QCOMPARE(spy11.count(), 1);
QVERIFY(!dock1->isFloating());
QVERIFY(!dock2->isFloating());
QVERIFY(!dock2->floatAction()->isChecked());
QVERIFY(!dock1->floatAction()->isChecked());
delete dock1->window();
delete oldFw2->window();
}
}
void TestCommon::tst_raise()
{
// Tests DockWidget::raise();
EnsureTopLevelsDeleted e;
auto dock1 = createDockWidget("1");
auto dock2 = createDockWidget("2");
auto fw2 = Tests::make_qpointer(dock2->window());
dock1->addDockWidgetAsTab(dock2);
dock1->setAsCurrentTab();
QVERIFY(dock1->isCurrentTab());
QVERIFY(!dock2->isCurrentTab());
dock2->raise();
QVERIFY(!dock1->isCurrentTab());
QVERIFY(dock2->isCurrentTab());
if (qApp->platformName() != QLatin1String("offscreen")) { // offscreen qpa doesn't seem to keep Window Z.
auto dock3 = createDockWidget("3");
dock3->window()->setGeometry(dock1->window()->geometry());
dock3->window()->setObjectName("3");
dock1->window()->setObjectName("1");
dock3->raise();
QTest::qWait(200);
if (qApp->QGuiApplication::topLevelAt(dock3->window()->geometry().topLeft() + QPoint(50, 50)) != dock3->windowHandle()) {
qDebug() << "Failing before raise" << qApp->widgetAt(dock3->window()->geometry().topLeft() + QPoint(50, 50))->window() << dock3->window()
<< dock1->window()->geometry() << dock3->window()->geometry();
QVERIFY(false);
}
dock1->raise();
QTest::qWait(200);
QVERIFY(dock1->isCurrentTab());
if (qApp->QGuiApplication::topLevelAt(dock3->window()->geometry().topLeft() + QPoint(50, 50)) != dock1->windowHandle()) {
qDebug() << "Failing after raise" << qApp->widgetAt(dock3->window()->geometry().topLeft() + QPoint(50, 50))->window() << dock1->window()
<< dock1->window()->geometry() << dock3->window()->geometry();
QVERIFY(false);
}
delete dock3->window();
}
delete fw2;
delete dock1->window();
}
#include "tst_common.moc"

View File

@@ -173,9 +173,6 @@ private Q_SLOTS:
void tst_addingOptionHiddenTabbed();
void tst_flagDoubleClick();
void tst_floatingWindowDeleted();
void tst_raise();
void tst_floatingAction();
void tst_dockableMainWindows();
void tst_maxSizedHonouredAfterRemoved();
void tst_maximumSizePolicy();
@@ -832,363 +829,6 @@ void TestDocks::tst_floatingWindowDeleted()
MyMainWindow m;
}
void TestDocks::tst_raise()
{
// Tests DockWidget::raise();
EnsureTopLevelsDeleted e;
auto dock1 = createDockWidget("1", new QWidget());
auto dock2 = createDockWidget("2", new QWidget());
auto fw2 = Tests::make_qpointer(dock2->window());
dock1->addDockWidgetAsTab(dock2);
dock1->setAsCurrentTab();
QVERIFY(dock1->isCurrentTab());
QVERIFY(!dock2->isCurrentTab());
dock2->raise();
QVERIFY(!dock1->isCurrentTab());
QVERIFY(dock2->isCurrentTab());
if (qApp->platformName() != QLatin1String("offscreen")) { // offscreen qpa doesn't seem to keep Window Z.
auto dock3 = createDockWidget("3", new QWidget());
dock3->window()->setGeometry(dock1->window()->geometry());
dock3->window()->setObjectName("3");
dock1->window()->setObjectName("1");
dock3->raise();
QTest::qWait(200);
if (qApp->widgetAt(dock3->window()->geometry().topLeft() + QPoint(50, 50))->window() != dock3->window()) {
qDebug() << "Failing before raise" << qApp->widgetAt(dock3->window()->geometry().topLeft() + QPoint(50, 50))->window() << dock3->window()
<< dock1->window()->geometry() << dock3->window()->geometry();
QVERIFY(false);
}
dock1->raise();
QTest::qWait(200);
QVERIFY(dock1->isCurrentTab());
if (qApp->widgetAt(dock3->window()->geometry().topLeft() + QPoint(50, 50))->window() != dock1->window()) {
qDebug() << "Failing after raise" << qApp->widgetAt(dock3->window()->geometry().topLeft() + QPoint(50, 50))->window() << dock1->window()
<< dock1->window()->geometry() << dock3->window()->geometry();
QVERIFY(false);
}
delete dock3->window();
}
delete fw2;
delete dock1->window();
}
void TestDocks::tst_floatingAction()
{
// Tests DockWidget::floatAction()
EnsureTopLevelsDeleted e;
{
// 1. Create a MainWindow with two docked dock-widgets, then float the first one.
auto m = createMainWindow();
auto dock1 = createDockWidget("dock1", new QPushButton("one"));
auto dock2 = createDockWidget("dock2", new QPushButton("two"));
m->addDockWidget(dock1, KDDockWidgets::Location_OnLeft);
m->addDockWidget(dock2, KDDockWidgets::Location_OnRight);
auto action = dock1->floatAction();
QVERIFY(!dock1->isFloating());
QVERIFY(!action->isChecked());
QVERIFY(action->isEnabled());
QCOMPARE(action->toolTip(), tr("Detach"));
action->toggle();
QVERIFY(dock1->isFloating());
QVERIFY(action->isChecked());
QVERIFY(action->isEnabled());
QCOMPARE(action->toolTip(), tr("Dock"));
auto fw = dock1->floatingWindow();
QVERIFY(fw);
//2. Put it back, via setFloating(). It should return to its place.
action->toggle();
QVERIFY(!dock1->isFloating());
QVERIFY(!action->isChecked());
QVERIFY(action->isEnabled());
QVERIFY(!dock1->isTabbed());
QCOMPARE(action->toolTip(), tr("Detach"));;
Testing::waitForDeleted(fw);
}
{
// 1. Create a MainWindow with one docked dock-widgets, and one floating.
auto m = createMainWindow();
auto dock1 = createDockWidget("dock1", new QPushButton("one"));
auto dock2 = createDockWidget("dock2", new QPushButton("two"));
m->addDockWidget(dock1, KDDockWidgets::Location_OnLeft);
//The floating window action should be disabled as it has no previous place
auto action = dock2->floatAction();
QVERIFY(dock2->isFloating());
QVERIFY(action->isChecked());
QVERIFY(!action->isEnabled());
QCOMPARE(action->toolTip(), tr("Dock"));
m->addDockWidget(dock2, KDDockWidgets::Location_OnRight);
QVERIFY(!dock2->isFloating());
QVERIFY(!action->isChecked());
QVERIFY(action->isEnabled());
QCOMPARE(action->toolTip(), tr("Detach"));
action->toggle();
QVERIFY(dock2->isFloating());
QVERIFY(action->isChecked());
QVERIFY(action->isEnabled());
QCOMPARE(action->toolTip(), tr("Dock"));
auto fw = dock2->floatingWindow();
QVERIFY(fw);
//2. Put it back, via setFloating(). It should return to its place.
action->toggle();
QVERIFY(!dock1->isFloating());
QVERIFY(!action->isChecked());
QVERIFY(action->isEnabled());
QVERIFY(!dock1->isTabbed());
QCOMPARE(action->toolTip(), tr("Detach"));
Testing::waitForDeleted(fw);
}
{
// 3. A floating window with two tabs
auto dock1 = createDockWidget("dock1", new QPushButton("one"));
auto dock2 = createDockWidget("dock2", new QPushButton("two"));
bool dock1IsFloating = dock1->floatAction()->isChecked();
bool dock2IsFloating = dock2->floatAction()->isChecked();
connect(dock1->floatAction(), &QAction::toggled, [&dock1IsFloating] (bool t) {
Q_ASSERT(dock1IsFloating != t);
dock1IsFloating = t;
});
connect(dock2->floatAction(), &QAction::toggled, [&dock2IsFloating] (bool t) {
Q_ASSERT(dock2IsFloating != t);
dock2IsFloating = t;
});
auto fw2 = dock2->floatingWindow();
QVERIFY(dock1->isFloating());
QVERIFY(dock2->isFloating());
QVERIFY(dock1->floatAction()->isChecked());
QVERIFY(dock2->floatAction()->isChecked());
dock1->addDockWidgetAsTab(dock2);
QVERIFY(!dock1->isFloating());
QVERIFY(!dock2->isFloating());
QVERIFY(!dock1->floatAction()->isChecked());
QVERIFY(!dock2->floatAction()->isChecked());
dock2->setFloating(true);
QVERIFY(dock1->isFloating());
QVERIFY(dock1->floatAction()->isChecked());
QVERIFY(dock2->isFloating());
QVERIFY(dock2->floatAction()->isChecked());
QVERIFY(dock1IsFloating);
QVERIFY(dock2IsFloating);
delete fw2;
delete dock1->window();
delete dock2->window();
}
{
// If the dock widget is alone then it's floating, but we suddenly dock a widget side-by-side
// to it, then both aren't floating anymore. This test tests if the signal was emitted
auto dock1 = createDockWidget("one", new QPushButton("one"));
auto dock2 = createDockWidget("two", new QPushButton("two"));
QVERIFY(dock1->isFloating());
QVERIFY(dock2->isFloating());
QVERIFY(dock1->floatAction()->isChecked());
QVERIFY(dock2->floatAction()->isChecked());
auto oldFw2 = dock2->window();
QSignalSpy spy1(dock1->floatAction(), &QAction::toggled);
QSignalSpy spy2(dock2->floatAction(), &QAction::toggled);
QSignalSpy spy11(dock1, &DockWidgetBase::isFloatingChanged);
QSignalSpy spy21(dock2, &DockWidgetBase::isFloatingChanged);
dock1->addDockWidgetToContainingWindow(dock2, Location_OnRight);
QCOMPARE(spy1.count(), 1);
QCOMPARE(spy2.count(), 1);
QCOMPARE(spy11.count(), 1);
QCOMPARE(spy21.count(), 1);
QVERIFY(!dock1->isFloating());
QVERIFY(!dock2->isFloating());
QVERIFY(!dock2->floatAction()->isChecked());
QVERIFY(!dock1->floatAction()->isChecked());
delete dock1->window();
delete oldFw2->window();
}
{
// Like before, but now we use addMultiSplitter()
auto dock1 = createDockWidget("one", new QPushButton("one"));
auto dock2 = createDockWidget("two", new QPushButton("two"));
QVERIFY(dock1->isFloating());
QVERIFY(dock2->isFloating());
QVERIFY(dock1->floatAction()->isChecked());
QVERIFY(dock2->floatAction()->isChecked());
auto oldFw2 = dock2->floatingWindow();
QSignalSpy spy1(dock1->floatAction(), &QAction::toggled);
QSignalSpy spy2(dock2->floatAction(), &QAction::toggled);
QSignalSpy spy11(dock1, &DockWidgetBase::isFloatingChanged);
QSignalSpy spy21(dock2, &DockWidgetBase::isFloatingChanged);
auto dropArea1 = dock1->floatingWindow()->dropArea();
dropArea1->drop(oldFw2, Location_OnRight, nullptr);
QCOMPARE(spy1.count(), 1);
QCOMPARE(spy2.count(), 1);
QCOMPARE(spy11.count(), 1);
QCOMPARE(spy21.count(), 1);
QVERIFY(!dock1->isFloating());
QVERIFY(!dock2->isFloating());
QVERIFY(!dock2->floatAction()->isChecked());
QVERIFY(!dock1->floatAction()->isChecked());
// Let's now remove dock1, dock2 should be floating
dock1->setFloating(true);
QVERIFY(dock1->isFloating());
QVERIFY(dock2->isFloating());
QVERIFY(dock2->floatAction()->isChecked());
QVERIFY(dock1->floatAction()->isChecked());
delete dock1->window();
delete dock2->window();
delete oldFw2->window();
}
{
// Same test as before, but now tab instead of side-by-side
auto dock1 = createDockWidget("one", new QPushButton("one"));
auto dock2 = createDockWidget("two", new QPushButton("two"));
QVERIFY(dock1->isFloating());
QVERIFY(dock2->isFloating());
QVERIFY(dock1->floatAction()->isChecked());
QVERIFY(dock2->floatAction()->isChecked());
auto oldFw2 = dock2->window();
QSignalSpy spy1(dock1->floatAction(), &QAction::toggled);
QSignalSpy spy2(dock2->floatAction(), &QAction::toggled);
QSignalSpy spy11(dock1, &DockWidgetBase::isFloatingChanged);
QSignalSpy spy21(dock2, &DockWidgetBase::isFloatingChanged);
dock1->addDockWidgetAsTab(dock2);
QCOMPARE(spy1.count(), 1);
// On earlier Qt versions this is flaky, but technically correct.
// Windows can get hidden while being reparented and floating changes momentarily.
QVERIFY(spy2.count() == 1 || spy2.count() == 3);
QVERIFY(spy21.count() == 1 || spy21.count() == 3);
QCOMPARE(spy11.count(), 1);
QVERIFY(!dock1->isFloating());
QVERIFY(!dock2->isFloating());
QVERIFY(!dock2->floatAction()->isChecked());
QVERIFY(!dock1->floatAction()->isChecked());
delete dock1->window();
delete oldFw2->window();
}
}
void TestDocks::tst_dockableMainWindows()
{
EnsureTopLevelsDeleted e;
auto m1 = createMainWindow();
auto dock1 = createDockWidget("dock1", new QPushButton("foo"));
m1->addDockWidget(dock1, Location_OnTop);
auto m2 = new KDDockWidgets::MainWindow("mainwindow-dockable");
auto m2Container = createDockWidget("mainwindow-dw", m2);
auto menubar = m2->menuBar();
menubar->addMenu("File");
menubar->addMenu("View");
menubar->addMenu("Help");
m2Container->show();
auto dock21 = createDockWidget("dock21", new QPushButton("foo"));
auto dock22 = createDockWidget("dock22", new QPushButton("foo"));
m2->addDockWidget(dock21, Location_OnLeft);
m2->addDockWidget(dock22, Location_OnRight);
auto fw = m2Container->floatingWindow();
TitleBar *fwTitleBar = fw->titleBar();
QVERIFY(fw->hasSingleFrame());
QVERIFY(fw->hasSingleDockWidget());
// Check that the inner-inner dock widgets have a visible title-bar
QVERIFY(dock21->titleBar()->isVisible());
QVERIFY(dock22->titleBar()->isVisible());
QVERIFY(dock21->titleBar() != fwTitleBar);
QVERIFY(dock22->titleBar() != fwTitleBar);
QTest::qWait(10); // the DND state machine needs the event loop to start, otherwise activeState() is nullptr. (for offscreen QPA)
const QPoint startPoint = fwTitleBar->mapToGlobal(QPoint(5, 5));
const QPoint destination = startPoint + QPoint(20, 20);
// Check that we don't get the "Refusing to itself" warning. not actually dropping anywhere
drag(fwTitleBar, startPoint, destination);
// The FloatingWindow has a single DockWidget, so it shows the title bar, while the Frame doesn't
QVERIFY(fwTitleBar->isVisible());
QVERIFY(!m2Container->frame()->titleBar()->isVisible());
fw->dropArea()->addDockWidget(dock1, Location::Location_OnLeft, nullptr);
// Now the FloatingWindow has two dock widgets, so our main window dock widget also shows the title bar
QVERIFY(fwTitleBar->isVisible());
QVERIFY(m2Container->frame()->titleBar()->isVisible());
// Put it how it was, FloatingWindow is single dock again
auto frame1 = dock1->frame();
dock1->close();
Testing::waitForDeleted(frame1);
QVERIFY(fwTitleBar->isVisible());
QVERIFY(!m2Container->frame()->titleBar()->isVisible());
// Repeat, but instead of closing dock1, we float it
fw->dropArea()->addDockWidget(dock1, Location::Location_OnLeft, nullptr);
QVERIFY(fwTitleBar->isVisible());
QVERIFY(m2Container->frame()->titleBar()->isVisible());
frame1 = dock1->frame();
frame1->titleBar()->onFloatClicked();
QVERIFY(fwTitleBar->isVisible());
QVERIFY(!m2Container->frame()->titleBar()->isVisible());
fw->dropArea()->addDockWidget(dock1, Location::Location_OnLeft, nullptr);
}
void TestDocks::tst_maxSizedHonouredAfterRemoved()
{
EnsureTopLevelsDeleted e;