diff --git a/CMakeLists.txt b/CMakeLists.txt index 889d6199f..db3299cb1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -78,8 +78,8 @@ project( ) set(KDDockWidgets_VERSION_MAJOR 2) -set(KDDockWidgets_VERSION_MINOR 0) -set(KDDockWidgets_VERSION_PATCH 95) +set(KDDockWidgets_VERSION_MINOR 1) +set(KDDockWidgets_VERSION_PATCH 1) set(KDDockWidgets_VERSION ${KDDockWidgets_VERSION_MAJOR}.${KDDockWidgets_VERSION_MINOR}.${KDDockWidgets_VERSION_PATCH}) set(PROJECT_VERSION ${KDDockWidgets_VERSION}) # PROJECT_VERSION is needed by some ECM modules set(KDDockWidgets_SOVERSION "2.1") diff --git a/Changelog b/Changelog index 0c77d6862..21a705f1e 100644 --- a/Changelog +++ b/Changelog @@ -1,4 +1,7 @@ -* v2.1.0 (unreleased) +* v2.1.1 (unreleased) + - + +* v2.1.0 (08 May 2024) - Added standalone layouting example using Slint - Fixed DPI of icons in TitleBar.qml Looks better when using 150% and 200% scalling now. - QtQuick: Fixed redock not working when mixing MDI with docking @@ -11,7 +14,6 @@ - QtWidgets: Introduced MainWindowOption_QDockWidgets and MainWindowOption_ManualInit - QtWidgets: Honours overriding DockWidget::closeEvent() to prevent closing - QtWidgets: Fixed crash when unpinning a window - - Planned: #448 Implement docking indicator for MDI area - Fix crash when doing sequential open() and close() calls (#326) - Fix double-clicking the guest widget would make window float - 3rdparty: Update to nlohmann json v3.11.3, from v3.10.5. Only relevant if you're not using diff --git a/conan/conanfile.py b/conan/conanfile.py index 624a6b594..50de0eac3 100644 --- a/conan/conanfile.py +++ b/conan/conanfile.py @@ -12,7 +12,7 @@ class KDDockWidgetsConan(ConanFile): name = "kddockwidgets" - version = "2.0.0" + version = "2.1.0" default_user = "kdab" default_channel = "stable" license = ("https://raw.githubusercontent.com/KDAB/KDDockWidgets/master/LICENSES/GPL-2.0-only.txt", diff --git a/distro/debian.changelog b/distro/debian.changelog index daeb26824..4098355e0 100644 --- a/distro/debian.changelog +++ b/distro/debian.changelog @@ -1,3 +1,9 @@ +kddockwidgets (2.1.0) release candidate; urgency=high + + * 2.1.0 final + + -- Allen Winter Wed, 08 May 2024 12:00:00 -0500 + kddockwidgets (2.0.0) release candidate; urgency=high * 2.0.0 final diff --git a/distro/qt5-kddockwidgets.dsc b/distro/qt5-kddockwidgets.dsc index 2fdc68e2d..ce02f150c 100644 --- a/distro/qt5-kddockwidgets.dsc +++ b/distro/qt5-kddockwidgets.dsc @@ -1,10 +1,10 @@ Format: 1.0 Source: kddockwidgets -Version: 2.0.0-1 +Version: 2.1.0-1 Binary: kddockwidgets Maintainer: Allen Winter Architecture: any Build-Depends: debhelper (>=9), cdbs, cmake, qtbase5-dev, qtbase5-private-dev, libqt5x11extras5-dev, libfontconfig-dev, libfreetype-dev Files: - 00000000000000000000000000000000 00000 qt5-kddockwidgets-2.0.0.tar.gz + 00000000000000000000000000000000 00000 qt5-kddockwidgets-2.1.0.tar.gz diff --git a/distro/qt5-kddockwidgets.spec b/distro/qt5-kddockwidgets.spec index 3022ca2fd..ffd6e1618 100644 --- a/distro/qt5-kddockwidgets.spec +++ b/distro/qt5-kddockwidgets.spec @@ -1,5 +1,5 @@ Name: qt5-kddockwidgets -Version: 2.0.0 +Version: 2.1.0 Release: 1 Summary: KDAB's Dock Widget Framework for Qt5 Source0: %{name}-%{version}.tar.gz @@ -98,6 +98,8 @@ cmake . -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release %{_libdir}/libkddockwidgets.so %changelog +* Wed May 08 2024 Allen Winter 2.1.0 + 2.1.0 final * Tue Dec 05 2023 Allen Winter 2.0.0 2.0.0 final * Wed May 03 2023 Allen Winter 1.7.0 diff --git a/distro/qt6-kddockwidgets.dsc b/distro/qt6-kddockwidgets.dsc index cd29e9478..22d4232d1 100644 --- a/distro/qt6-kddockwidgets.dsc +++ b/distro/qt6-kddockwidgets.dsc @@ -1,10 +1,10 @@ Format: 1.0 Source: kddockwidgets -Version: 2.0.0-1 +Version: 2.1.0-1 Binary: kddockwidgets Maintainer: Allen Winter Architecture: any Build-Depends: debhelper (>=9), cdbs, cmake, qt6-base-dev, qt6-base-private-dev, libgl1-mesa-dev, libfontconfig-dev, libfreetype-dev Files: - 00000000000000000000000000000000 00000 qt6-kddockwidgets-2.0.0.tar.gz + 00000000000000000000000000000000 00000 qt6-kddockwidgets-2.1.0.tar.gz diff --git a/distro/qt6-kddockwidgets.spec b/distro/qt6-kddockwidgets.spec index 0c54e6b91..87e491749 100644 --- a/distro/qt6-kddockwidgets.spec +++ b/distro/qt6-kddockwidgets.spec @@ -1,5 +1,5 @@ Name: qt6-kddockwidgets -Version: 2.0.0 +Version: 2.1.0 Release: 1 Summary: KDAB's Dock Widget Framework for Qt6 Source0: %{name}-%{version}.tar.gz @@ -87,6 +87,8 @@ cmake . -DCMAKE_INSTALL_PREFIX=/usr -DKDDockWidgets_QT6=True -DCMAKE_BUILD_TYPE= %{_libdir}/qt6/mkspecs/modules/* %changelog +* Wed May 08 2024 Allen Winter 2.1.0 + 2.1.0 final * Tue Dec 05 2023 Allen Winter 2.0.0 2.0.0 final * Wed May 03 2023 Allen Winter 1.7.0 diff --git a/src/LayoutSaver.cpp b/src/LayoutSaver.cpp index 4e764478d..7f87a712c 100644 --- a/src/LayoutSaver.cpp +++ b/src/LayoutSaver.cpp @@ -527,21 +527,14 @@ bool LayoutSaver::restoreLayout(const QByteArray &data) if (!(d->m_restoreOptions & InternalRestoreOption::SkipMainWindowGeometry)) { Window::Ptr window = mainWindow->view()->window(); - - if (window->windowState() == WindowState::Maximized && mw.windowState != WindowState::Maximized) { - // Never call deserializeWindowGeometry() on a maximized window. - // If window is maximized and we're restoring it to "normal", then 1st change state, then set geometry - window->setWindowState(mw.windowState); - d->deserializeWindowGeometry(mw, window); - } else if (mw.windowState != window->windowState()) { - // If window is normal and we're restoring it to maximized, then set geometry 1st - // so its normal geometry gets remembered, only then maximize - - d->deserializeWindowGeometry(mw, window); - window->setWindowState(mw.windowState); - } else { - d->deserializeWindowGeometry(mw, window); + if (window->windowState() == WindowState::Maximized) { + // Restoring geometry needs to be done in normal state. + // Qt doesn't support restoring normal geometry on maximized windows. + window->setWindowState(WindowState::None); } + + d->deserializeWindowGeometry(mw, window); + window->setWindowState(mw.windowState); } if (!mainWindow->deserialize(mw)) diff --git a/src/core/layouting/Item.cpp b/src/core/layouting/Item.cpp index d8f828bfd..2bae8f5d7 100644 --- a/src/core/layouting/Item.cpp +++ b/src/core/layouting/Item.cpp @@ -3735,6 +3735,11 @@ LayoutingSeparator *ItemBoxContainer::adjacentSeparatorForChild(Item *child, Sid return nullptr; } +bool ItemBoxContainer::isDeserializing() const +{ + return d->m_isDeserializing; +} + bool ItemBoxContainer::isOverflowing() const { // This never returns true, unless when loading a buggy layout diff --git a/src/core/layouting/Item_p.h b/src/core/layouting/Item_p.h index f6f5d8705..40bc61bdf 100644 --- a/src/core/layouting/Item_p.h +++ b/src/core/layouting/Item_p.h @@ -463,6 +463,7 @@ class DOCKS_EXPORT ItemBoxContainer : public ItemContainer int length() const; bool hasOrientation() const; bool isOverflowing() const; + bool isDeserializing() const; /// @brief Returns the number of visible items layed-out horizontally or vertically /// But honours nesting diff --git a/src/qtquick/DockWidgetInstantiator.cpp b/src/qtquick/DockWidgetInstantiator.cpp index d2a80ad43..e17ac1c07 100644 --- a/src/qtquick/DockWidgetInstantiator.cpp +++ b/src/qtquick/DockWidgetInstantiator.cpp @@ -16,35 +16,71 @@ #include "Config.h" #include "Platform.h" +#include + using namespace KDDockWidgets; using namespace KDDockWidgets::QtQuick; +class DockWidgetInstantiator::Private +{ +public: + std::optional m_isFloating; + QString m_uniqueName; + QString m_sourceFilename; + QString m_title; + Core::DockWidget *m_dockWidget = nullptr; + QVector m_affinities; + + KDBindings::ScopedConnection titleConnection; + KDBindings::ScopedConnection closedConnection; + KDBindings::ScopedConnection iconConnection; + KDBindings::ScopedConnection actualTitleBarConnection; + KDBindings::ScopedConnection optionsConnection; + KDBindings::ScopedConnection windowActiveAboutToChangeConnection; + KDBindings::ScopedConnection isOverlayedConnection; + KDBindings::ScopedConnection isFocusedConnection; + KDBindings::ScopedConnection isFloatingConnection; + KDBindings::ScopedConnection isOpenConnection; + KDBindings::ScopedConnection guestViewChangedConnection; + KDBindings::ScopedConnection removedFromSideBarConnection; +}; + +DockWidgetInstantiator::DockWidgetInstantiator() + : d(new Private()) +{ +} + +DockWidgetInstantiator::~DockWidgetInstantiator() +{ + delete d; +} + QString DockWidgetInstantiator::uniqueName() const { - return m_uniqueName; + return d->m_uniqueName; } void DockWidgetInstantiator::setUniqueName(const QString &name) { - m_uniqueName = name; + d->m_uniqueName = name; Q_EMIT uniqueNameChanged(); } QString DockWidgetInstantiator::source() const { - return m_sourceFilename; + return d->m_sourceFilename; } void DockWidgetInstantiator::setSource(const QString &source) { - m_sourceFilename = source; + d->m_sourceFilename = source; Q_EMIT sourceChanged(); } QtQuick::DockWidget *DockWidgetInstantiator::dockWidget() const { - if (m_dockWidget) { - return static_cast(m_dockWidget->view()); + if (d->m_dockWidget) { + return static_cast(d->m_dockWidget->view()); } return nullptr; @@ -52,7 +88,7 @@ QtQuick::DockWidget *DockWidgetInstantiator::dockWidget() const KDDockWidgets::Core::DockWidget *DockWidgetInstantiator::controller() const { - return m_dockWidget; + return d->m_dockWidget; } QObject *DockWidgetInstantiator::actualTitleBar() const @@ -66,45 +102,45 @@ QObject *DockWidgetInstantiator::actualTitleBar() const QString DockWidgetInstantiator::title() const { - return m_dockWidget ? m_dockWidget->title() : QString(); + return d->m_dockWidget ? d->m_dockWidget->title() : QString(); } void DockWidgetInstantiator::setTitle(const QString &title) { - if (m_dockWidget) - m_dockWidget->setTitle(title); - m_title = title; + if (d->m_dockWidget) + d->m_dockWidget->setTitle(title); + d->m_title = title; } bool DockWidgetInstantiator::isFocused() const { - return m_dockWidget && m_dockWidget->isFocused(); + return d->m_dockWidget && d->m_dockWidget->isFocused(); } bool DockWidgetInstantiator::isFloating() const { - return m_dockWidget && m_dockWidget->isFloating(); + return d->m_dockWidget && d->m_dockWidget->isFloating(); } bool DockWidgetInstantiator::isOpen() const { - return m_dockWidget && m_dockWidget->isOpen(); + return d->m_dockWidget && d->m_dockWidget->isOpen(); } void DockWidgetInstantiator::setFloating(bool is) { - if (m_dockWidget) - m_dockWidget->setFloating(is); - m_isFloating = is; + if (d->m_dockWidget) + d->m_dockWidget->setFloating(is); + d->m_isFloating = is; } void DockWidgetInstantiator::addDockWidgetAsTab(QQuickItem *other, InitialVisibilityOption option) { - if (!other || !m_dockWidget) + if (!other || !d->m_dockWidget) return; Core::DockWidget *otherDockWidget = Platform::dockWidgetForItem(other); - m_dockWidget->addDockWidgetAsTab(otherDockWidget, option); + d->m_dockWidget->addDockWidgetAsTab(otherDockWidget, option); } void DockWidgetInstantiator::addDockWidgetToContainingWindow(QQuickItem *other, Location location, @@ -112,40 +148,40 @@ void DockWidgetInstantiator::addDockWidgetToContainingWindow(QQuickItem *other, QSize initialSize, InitialVisibilityOption option) { - if (!other || !m_dockWidget) + if (!other || !d->m_dockWidget) return; Core::DockWidget *otherDockWidget = Platform::dockWidgetForItem(other); Core::DockWidget *relativeToDockWidget = Platform::dockWidgetForItem(relativeTo); - m_dockWidget->addDockWidgetToContainingWindow(otherDockWidget, location, relativeToDockWidget, - InitialOption(option, initialSize)); + d->m_dockWidget->addDockWidgetToContainingWindow(otherDockWidget, location, relativeToDockWidget, + InitialOption(option, initialSize)); } void DockWidgetInstantiator::setAsCurrentTab() { - if (m_dockWidget) - m_dockWidget->setAsCurrentTab(); + if (d->m_dockWidget) + d->m_dockWidget->setAsCurrentTab(); } void DockWidgetInstantiator::forceClose() { - if (m_dockWidget) - m_dockWidget->forceClose(); + if (d->m_dockWidget) + d->m_dockWidget->forceClose(); } Q_INVOKABLE bool DockWidgetInstantiator::close() { - if (m_dockWidget) - return m_dockWidget->close(); + if (d->m_dockWidget) + return d->m_dockWidget->close(); return false; } void DockWidgetInstantiator::open() { - if (m_dockWidget) - m_dockWidget->open(); + if (d->m_dockWidget) + d->m_dockWidget->open(); } void DockWidgetInstantiator::show() @@ -156,19 +192,19 @@ void DockWidgetInstantiator::show() void DockWidgetInstantiator::raise() { - if (m_dockWidget) - m_dockWidget->raise(); + if (d->m_dockWidget) + d->m_dockWidget->raise(); } void DockWidgetInstantiator::moveToSideBar() { - if (m_dockWidget) - m_dockWidget->moveToSideBar(); + if (d->m_dockWidget) + d->m_dockWidget->moveToSideBar(); } void DockWidgetInstantiator::deleteDockWidget() { - delete m_dockWidget; + delete d->m_dockWidget; delete this; } @@ -179,75 +215,75 @@ void DockWidgetInstantiator::classBegin() QVector DockWidgetInstantiator::affinities() const { - return m_dockWidget ? m_dockWidget->affinities() : QVector(); + return d->m_dockWidget ? d->m_dockWidget->affinities() : QVector(); } void DockWidgetInstantiator::setAffinities(const QVector &affinities) { - if (m_affinities != affinities) { - m_affinities = affinities; + if (d->m_affinities != affinities) { + d->m_affinities = affinities; Q_EMIT affinitiesChanged(); } } void DockWidgetInstantiator::componentComplete() { - if (m_uniqueName.isEmpty()) { + if (d->m_uniqueName.isEmpty()) { qWarning() << Q_FUNC_INFO << "Each DockWidget need an unique name. Set the uniqueName property."; return; } - if (DockRegistry::self()->containsDockWidget(m_uniqueName)) { + if (DockRegistry::self()->containsDockWidget(d->m_uniqueName)) { // Dock widget already exists. all good. return; } - if (m_dockWidget) { + if (d->m_dockWidget) { qWarning() << Q_FUNC_INFO << "Unexpected bug."; return; } const auto childItems = this->childItems(); - if (m_sourceFilename.isEmpty() && childItems.size() != 1) { + if (d->m_sourceFilename.isEmpty() && childItems.size() != 1) { qWarning() << Q_FUNC_INFO << "Either 'source' property must be set or add exactly one child" - << "; source=" << m_sourceFilename << "; num children=" << childItems.size(); + << "; source=" << d->m_sourceFilename << "; num children=" << childItems.size(); return; } - m_dockWidget = ViewFactory::self() - ->createDockWidget(m_uniqueName, qmlEngine(this)) - ->asDockWidgetController(); + d->m_dockWidget = ViewFactory::self() + ->createDockWidget(d->m_uniqueName, qmlEngine(this)) + ->asDockWidgetController(); - m_dockWidget->d->titleChanged.connect([this](const QString &title) { Q_EMIT titleChanged(title); }); - m_dockWidget->d->closed.connect([this] { Q_EMIT closed(); }); - m_dockWidget->d->iconChanged.connect([this] { Q_EMIT iconChanged(); }); - m_dockWidget->d->actualTitleBarChanged.connect([this] { Q_EMIT actualTitleBarChanged(); }); - m_dockWidget->d->optionsChanged.connect([this](KDDockWidgets::DockWidgetOptions opts) { Q_EMIT optionsChanged(opts); }); + d->titleConnection = d->m_dockWidget->d->titleChanged.connect([this](const QString &title) { Q_EMIT titleChanged(title); }); + d->closedConnection = d->m_dockWidget->d->closed.connect([this] { Q_EMIT closed(); }); + d->iconConnection = d->m_dockWidget->d->iconChanged.connect([this] { Q_EMIT iconChanged(); }); + d->actualTitleBarConnection = d->m_dockWidget->d->actualTitleBarChanged.connect([this] { Q_EMIT actualTitleBarChanged(); }); + d->optionsConnection = d->m_dockWidget->d->optionsChanged.connect([this](KDDockWidgets::DockWidgetOptions opts) { Q_EMIT optionsChanged(opts); }); - m_dockWidget->d->windowActiveAboutToChange.connect([this](bool is) { Q_EMIT windowActiveAboutToChange(is); }); - m_dockWidget->d->isFocusedChanged.connect([this](bool is) { Q_EMIT isFocusedChanged(is); }); + d->windowActiveAboutToChangeConnection = d->m_dockWidget->d->windowActiveAboutToChange.connect([this](bool is) { Q_EMIT windowActiveAboutToChange(is); }); + d->isFocusedConnection = d->m_dockWidget->d->isFocusedChanged.connect([this](bool is) { Q_EMIT isFocusedChanged(is); }); - m_dockWidget->d->isOverlayedChanged.connect([this](bool is) { Q_EMIT isOverlayedChanged(is); }); - m_dockWidget->d->isFloatingChanged.connect([this](bool is) { Q_EMIT isFloatingChanged(is); }); - m_dockWidget->d->isOpenChanged.connect([this](bool is) { Q_EMIT isOpenChanged(is); }); + d->isOverlayedConnection = d->m_dockWidget->d->isOverlayedChanged.connect([this](bool is) { Q_EMIT isOverlayedChanged(is); }); + d->isFloatingConnection = d->m_dockWidget->d->isFloatingChanged.connect([this](bool is) { Q_EMIT isFloatingChanged(is); }); + d->isOpenConnection = d->m_dockWidget->d->isOpenChanged.connect([this](bool is) { Q_EMIT isOpenChanged(is); }); - m_dockWidget->d->guestViewChanged.connect([this] { Q_EMIT guestViewChanged(QtQuick::asQQuickItem(m_dockWidget->guestView().get())); }); - m_dockWidget->d->removedFromSideBar.connect([this] { Q_EMIT removedFromSideBar(); }); + d->guestViewChangedConnection = d->m_dockWidget->d->guestViewChanged.connect([this] { Q_EMIT guestViewChanged(QtQuick::asQQuickItem(d->m_dockWidget->guestView().get())); }); + d->removedFromSideBarConnection = d->m_dockWidget->d->removedFromSideBar.connect([this] { Q_EMIT removedFromSideBar(); }); auto view = this->dockWidget(); - if (m_sourceFilename.isEmpty()) { + if (d->m_sourceFilename.isEmpty()) { view->setGuestItem(childItems.constFirst()); } else { - view->setGuestItem(m_sourceFilename); + view->setGuestItem(d->m_sourceFilename); } - if (!m_title.isEmpty()) - m_dockWidget->setTitle(m_title); + if (!d->m_title.isEmpty()) + d->m_dockWidget->setTitle(d->m_title); - if (m_isFloating.has_value()) - m_dockWidget->setFloating(m_isFloating.value()); + if (d->m_isFloating.has_value()) + d->m_dockWidget->setFloating(d->m_isFloating.value()); - m_dockWidget->setAffinities(m_affinities); + d->m_dockWidget->setAffinities(d->m_affinities); Q_EMIT dockWidgetChanged(); } diff --git a/src/qtquick/DockWidgetInstantiator.h b/src/qtquick/DockWidgetInstantiator.h index 4b2f7e4f7..696120e50 100644 --- a/src/qtquick/DockWidgetInstantiator.h +++ b/src/qtquick/DockWidgetInstantiator.h @@ -46,6 +46,9 @@ class DockWidgetInstantiator : public QQuickItem Q_PROPERTY(bool isOpen READ isOpen NOTIFY isOpenChanged) Q_PROPERTY(QVector affinities READ affinities WRITE setAffinities NOTIFY affinitiesChanged) public: + DockWidgetInstantiator(); + ~DockWidgetInstantiator() override; + QString uniqueName() const; void setUniqueName(const QString &); @@ -114,12 +117,8 @@ class DockWidgetInstantiator : public QQuickItem void affinitiesChanged(); private: - std::optional m_isFloating; - QString m_uniqueName; - QString m_sourceFilename; - QString m_title; - Core::DockWidget *m_dockWidget = nullptr; - QVector m_affinities; + class Private; + Private *const d; }; } diff --git a/src/qtwidgets/views/Group.cpp b/src/qtwidgets/views/Group.cpp index 7fee2bd29..ccf9f890b 100644 --- a/src/qtwidgets/views/Group.cpp +++ b/src/qtwidgets/views/Group.cpp @@ -50,7 +50,7 @@ class VBoxLayout : public QVBoxLayout // clazy:exclude=missing-qobject-macro if (auto item = m_groupWidget->group()->layoutItem()) { if (auto root = item->root()) { - if (root->inSetSize()) { + if (root->inSetSize() || root->isDeserializing()) { // There's at least one item currently in the middle of a resize // schedule relayout, do not interrupt. QTimer::singleShot(0, m_groupWidget, [this] { diff --git a/tests/tst_native_qpa.cpp b/tests/tst_native_qpa.cpp index 3da92f363..3418c720f 100644 --- a/tests/tst_native_qpa.cpp +++ b/tests/tst_native_qpa.cpp @@ -42,6 +42,7 @@ public Q_SLOTS: private Q_SLOTS: void tst_restoreNormalFromMaximized(); void tst_restoreMaximizedFromNormal(); + void tst_restoreMaximizedFromMaximized(); }; void TestNativeQPA::initTestCase() @@ -140,7 +141,7 @@ void TestNativeQPA::tst_restoreNormalFromMaximized() void TestNativeQPA::tst_restoreMaximizedFromNormal() { - if (qApp->platformName() == QLatin1String("offscreen")) { + if (qGuiApp->platformName() == QLatin1String("offscreen")) { // offscreen: calling showMaximized() on an hidden widget, puts it at pos=2,2 instead of 0,0 // Ignore this QPA. This file is for testing native QPAs only. offscreen is nice to have // if it beahaves well only. @@ -199,6 +200,76 @@ void TestNativeQPA::tst_restoreMaximizedFromNormal() QCOMPARE(m->geometry(), expectedMaximizedGeometry); } +void TestNativeQPA::tst_restoreMaximizedFromMaximized() +{ + if (qApp->platformName() == QLatin1String("offscreen")) { + // offscreen: calling showMaximized() on an hidden widget, puts it at pos=2,2 instead of 0,0 + // Ignore this QPA. This file is for testing native QPAs only. offscreen is nice to have + // if it beahaves well only. + return; + } + +#ifdef Q_OS_MACOS + if (Platform::instance()->isQtQuick()) + return; +#endif + + // whitelist some macOS warning + SetExpectedWarning warn("invalid window content view size"); + + // Saves the window state while in maximized state, then restores after the window is shown normal + // the window should become maximized again. + // qDebug() << qApp->primaryScreen()->geometry(); + const QSize initialSize(500, 500); + auto m = createMainWindow(initialSize, MainWindowOption_None, "m1", false); + + auto windowptr = m->view()->window(); + auto window = static_cast(windowptr.get()); + QWindow *qtwindow = window->qtWindow(); + MyEventFilter filter; + qtwindow->installEventFilter(&filter); + + m->view()->showMaximized(); + QVERIFY(filter.waitForState(Qt::WindowMaximized)); + + int count = 0; + // Qt annoyingly sends us 2 or 3 resize events before the fully maximized one, even when + // already having state==Qt::WindowMaximized. Probably depends on platform. + // Consume all resize events until window gets big. + while (m->geometry().size().width() < 700) { + QVERIFY(Platform::instance()->tests_waitForResize(m->view())); + count++; + QVERIFY(count < 5); + } + + const auto expectedMaximizedGeometry = m->geometry(); + QVERIFY(initialSize != expectedMaximizedGeometry.size()); + + LayoutSaver saver; + const QByteArray saved = saver.serializeLayout(); + + QTest::qWait(1000); + + QVERIFY(saver.restoreLayout(saved)); + QVERIFY(filter.waitForState(Qt::WindowMaximized)); + + // Catch more resizes: + QTest::qWait(1000); + +#if QT_VERSION > QT_VERSION_CHECK(6, 0, 0) +#ifdef Q_OS_LINUX + if (Platform::instance()->isQtWidgets()) { + // buggy on Linux, Qt6, QtWidgets. The window is visually maximixed but geometry is wrong + return; + } +#endif +#endif + + + + QCOMPARE(m->geometry(), expectedMaximizedGeometry); +} + int main(int argc, char *argv[]) { #ifdef Q_OS_LINUX @@ -215,7 +286,7 @@ int main(int argc, char *argv[]) int exitCode = 0; for (FrontendType type : Platform::frontendTypes()) { KDDockWidgets::Core::Platform::tests_initPlatform(argc, argv, type, /*defaultToOffscreenQPA=*/false); - qDebug() << "\nTesting platform" << type << "on" << qApp->platformName() << "\n"; + qDebug() << "\nTesting platform" << type << "on" << qGuiApp->platformName() << "\n"; TestNativeQPA test;