summaryrefslogtreecommitdiffstats
path: root/src/dialogs/qquickabstractdialog.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/dialogs/qquickabstractdialog.cpp')
-rw-r--r--src/dialogs/qquickabstractdialog.cpp110
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();
}