diff options
Diffstat (limited to 'src/dialogs/qquickabstractdialog.cpp')
| -rw-r--r-- | src/dialogs/qquickabstractdialog.cpp | 110 |
1 files changed, 85 insertions, 25 deletions
diff --git a/src/dialogs/qquickabstractdialog.cpp b/src/dialogs/qquickabstractdialog.cpp index 41aa1bdcc..92fd04f4e 100644 --- a/src/dialogs/qquickabstractdialog.cpp +++ b/src/dialogs/qquickabstractdialog.cpp @@ -35,6 +35,8 @@ #include "qquickitem.h" #include <private/qguiapplication_p.h> +#include <private/qqmlglobal_p.h> +#include <QLoggingCategory> #include <QWindow> #include <QQmlComponent> #include <QQuickWindow> @@ -42,6 +44,8 @@ QT_BEGIN_NAMESPACE +Q_LOGGING_CATEGORY(lcWindow, "qt.quick.dialogs.window") + QQmlComponent *QQuickAbstractDialog::m_decorationComponent(0); QQuickAbstractDialog::QQuickAbstractDialog(QObject *parent) @@ -70,6 +74,7 @@ void QQuickAbstractDialog::setVisible(bool v) if (m_visible == v) return; m_visible = v; if (helper()) { + qCDebug(lcWindow) << "via helper" << helper(); if (v) { Qt::WindowFlags flags = Qt::Dialog; if (!title().isEmpty()) @@ -88,6 +93,7 @@ void QQuickAbstractDialog::setVisible(bool v) if (!m_dialogWindow && m_hasNativeWindows) { QQuickWindow *win = new QQuickWindow; ((QObject *)win)->setParent(this); // memory management only + win->setFlags(Qt::Dialog); m_dialogWindow = win; m_contentItem->setParentItem(win->contentItem()); QSize minSize = QSize(m_contentItem->implicitWidth(), m_contentItem->implicitHeight()); @@ -106,33 +112,43 @@ void QQuickAbstractDialog::setVisible(bool v) m_dialogWindow->setMinimumSize(minSize); connect(win, SIGNAL(widthChanged(int)), this, SLOT(windowGeometryChanged())); connect(win, SIGNAL(heightChanged(int)), this, SLOT(windowGeometryChanged())); + qCDebug(lcWindow) << "created window" << win; } - QQuickItem *parentItem = qobject_cast<QQuickItem *>(parent()); - - // If the platform does not support multiple windows, but the dialog is - // implemented as an Item, then try to decorate it as a fake window and make it visible. - if (parentItem && !m_dialogWindow && !m_windowDecoration) { - if (m_decorationComponent) { - if (m_decorationComponent->isLoading()) - connect(m_decorationComponent, SIGNAL(statusChanged(QQmlComponent::Status)), - this, SLOT(decorationLoaded())); - else - decorationLoaded(); + if (!m_dialogWindow) { + if (Q_UNLIKELY(!parentWindow())) { + qWarning("cannot set dialog visible: no window"); + return; } - // Window decoration wasn't possible, so just reparent it into the scene - else { - m_contentItem->setParentItem(parentItem); - m_contentItem->setZ(10000); + m_dialogWindow = parentWindow(); + + // If the platform does not support multiple windows, but the dialog is + // implemented as an Item, then try to decorate it as a fake window and make it visible. + if (!m_windowDecoration) { + if (m_decorationComponent) { + if (m_decorationComponent->isLoading()) + connect(m_decorationComponent, SIGNAL(statusChanged(QQmlComponent::Status)), + this, SLOT(decorationLoaded())); + else + decorationLoaded(); // do the reparenting of contentItem on top of it + } + // Window decoration wasn't possible, so just reparent it into the scene + else { + qCDebug(lcWindow) << "no window and no decoration"; + m_contentItem->setParentItem(parentWindow()->contentItem()); + m_contentItem->setZ(10000); + } } } } if (m_dialogWindow) { // "grow up" to the size and position expected to achieve if (!m_sizeAspiration.isNull()) { - if (m_hasAspiredPosition) + if (m_hasAspiredPosition) { + qCDebug(lcWindow) << "geometry aspiration" << m_sizeAspiration; m_dialogWindow->setGeometry(m_sizeAspiration); - else { + } else { + qCDebug(lcWindow) << "size aspiration" << m_sizeAspiration.size(); if (m_sizeAspiration.width() > 0) m_dialogWindow->setWidth(m_sizeAspiration.width()); if (m_sizeAspiration.height() > 0) @@ -142,6 +158,7 @@ void QQuickAbstractDialog::setVisible(bool v) connect(m_dialogWindow, SIGNAL(yChanged(int)), this, SLOT(setY(int))); connect(m_dialogWindow, SIGNAL(widthChanged(int)), this, SLOT(setWidth(int))); connect(m_dialogWindow, SIGNAL(heightChanged(int)), this, SLOT(setHeight(int))); + connect(m_contentItem, SIGNAL(implicitHeightChanged()), this, SLOT(implicitHeightChanged())); } if (!m_visibleChangedConnected) { connect(m_dialogWindow, SIGNAL(visibleChanged(bool)), this, SLOT(visibleChanged(bool))); @@ -166,9 +183,9 @@ void QQuickAbstractDialog::setVisible(bool v) void QQuickAbstractDialog::decorationLoaded() { bool ok = false; - QQuickItem *parentItem = qobject_cast<QQuickItem *>(parent()); - while (parentItem->parentItem() && !parentItem->parentItem()->inherits("QQuickRootItem")) - parentItem = parentItem->parentItem(); + Q_ASSERT(parentWindow()); + QQuickItem *parentItem = parentWindow()->contentItem(); + Q_ASSERT(parentItem); if (m_decorationComponent->isError()) { qWarning() << m_decorationComponent->errors(); } else { @@ -182,6 +199,7 @@ void QQuickAbstractDialog::decorationLoaded() m_windowDecoration->setProperty("content", contentVariant); connect(m_windowDecoration, SIGNAL(dismissed()), this, SLOT(reject())); ok = true; + qCDebug(lcWindow) << "using synthetic window decoration" << m_windowDecoration; } else { qWarning() << m_decorationComponent->url() << "cannot be used as a window decoration because it's not an Item"; @@ -194,12 +212,14 @@ void QQuickAbstractDialog::decorationLoaded() if (!ok) { m_contentItem->setParentItem(parentItem); m_contentItem->setZ(10000); + qCDebug(lcWindow) << "no decoration"; } } void QQuickAbstractDialog::setModality(Qt::WindowModality m) { if (m_modality == m) return; + qCDebug(lcWindow) << "modality" << m; m_modality = m; emit modalityChanged(); } @@ -219,12 +239,14 @@ void QQuickAbstractDialog::reject() void QQuickAbstractDialog::visibleChanged(bool v) { m_visible = v; + qCDebug(lcWindow) << "visible" << v; emit visibilityChanged(); } void QQuickAbstractDialog::windowGeometryChanged() { if (m_dialogWindow && m_contentItem) { + qCDebug(lcWindow) << m_dialogWindow->geometry(); m_contentItem->setWidth(m_dialogWindow->width()); m_contentItem->setHeight(m_dialogWindow->height()); } @@ -232,27 +254,42 @@ void QQuickAbstractDialog::windowGeometryChanged() void QQuickAbstractDialog::minimumWidthChanged() { - m_dialogWindow->setMinimumWidth(qMax(m_contentItem->implicitWidth(), - m_contentItem->property("minimumWidth").toReal())); + qreal min = m_contentItem->property("minimumWidth").toReal(); + qCDebug(lcWindow) << "content implicitWidth" << m_contentItem->implicitWidth() << "minimumWidth" << min; + m_dialogWindow->setMinimumWidth(qMax(m_contentItem->implicitWidth(), min)); } void QQuickAbstractDialog::minimumHeightChanged() { + qreal min = m_contentItem->property("minimumHeight").toReal(); + qCDebug(lcWindow) << "content implicitHeight" << m_contentItem->implicitHeight() << "minimumHeight" << min; m_dialogWindow->setMinimumHeight(qMax(m_contentItem->implicitHeight(), m_contentItem->property("minimumHeight").toReal())); } +void QQuickAbstractDialog::implicitHeightChanged() +{ + qCDebug(lcWindow) << "content implicitHeight" << m_contentItem->implicitHeight() + << "window minimumHeight" << m_dialogWindow->minimumHeight(); + if (m_contentItem->implicitHeight() < m_dialogWindow->minimumHeight()) + m_dialogWindow->setMinimumHeight(m_contentItem->implicitHeight()); +} + QQuickWindow *QQuickAbstractDialog::parentWindow() { - QQuickItem *parentItem = qobject_cast<QQuickItem *>(parent()); - if (parentItem) - m_parentWindow = parentItem->window(); + if (!m_parentWindow) { + // Usually a dialog is declared inside an Item; but if its QObject parent + // is a Window, that's the window we are interested in. (QTBUG-38578) + QQuickItem *parentItem = qobject_cast<QQuickItem *>(parent()); + m_parentWindow = (parentItem ? parentItem->window() : qmlobject_cast<QQuickWindow *>(parent())); + } return m_parentWindow; } void QQuickAbstractDialog::setContentItem(QQuickItem *obj) { m_contentItem = obj; + qCDebug(lcWindow) << obj; if (m_dialogWindow) { disconnect(this, SLOT(visibleChanged(bool))); // Can't necessarily delete because m_dialogWindow might have been provided by the QML. @@ -288,6 +325,25 @@ int QQuickAbstractDialog::height() const return m_sizeAspiration.height(); } +/* + A non-fullscreen dialog is not allowed to be too large + to fit on the screen in either orientation (portrait or landscape). + That way on platforms which can do rotation, the dialog does not + change its size when the screen is rotated. So the value returned + here is the maximum for both width and height. We need to know + at init time, not wait until the dialog's content item is shown in + a window so that the desktopAvailableWidth and Height will be valid + in the Screen attached property. And to allow space for window borders, + the max is further reduced by 10%. +*/ +int QQuickAbstractDialog::__maximumDimension() const +{ + QScreen *screen = QGuiApplication::primaryScreen(); + return (screen ? + qMin(screen->availableVirtualGeometry().width(), screen->availableVirtualGeometry().height()) : + 480) * 9 / 10; +} + void QQuickAbstractDialog::setX(int arg) { m_hasAspiredPosition = true; @@ -300,6 +356,7 @@ void QQuickAbstractDialog::setX(int arg) } else if (m_contentItem) { m_contentItem->setX(arg); } + qCDebug(lcWindow) << arg; emit geometryChanged(); } @@ -315,6 +372,7 @@ void QQuickAbstractDialog::setY(int arg) } else if (m_contentItem) { m_contentItem->setY(arg); } + qCDebug(lcWindow) << arg; emit geometryChanged(); } @@ -329,6 +387,7 @@ void QQuickAbstractDialog::setWidth(int arg) } else if (m_contentItem) { m_contentItem->setWidth(arg); } + qCDebug(lcWindow) << arg; emit geometryChanged(); } @@ -343,6 +402,7 @@ void QQuickAbstractDialog::setHeight(int arg) } else if (m_contentItem) { m_contentItem->setHeight(arg); } + qCDebug(lcWindow) << arg; emit geometryChanged(); } |
