diff options
author | Tor Arne Vestbø <tor.arne.vestbo@digia.com> | 2013-11-27 17:57:25 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-11-30 17:56:22 +0100 |
commit | d0644b040eb09e1ed147ff15e7c926c9e318cbca (patch) | |
tree | 2c6d9d08fc521c13c80cbeb300655042a3ef2870 /src/quick/items/qquickwindowmodule.cpp | |
parent | a6348870ee1fc7b0270ceebf0f13dee7e5e54719 (diff) |
Ensure that QML Windows respect the default platform window state
The 'visible' property of a Window would be set on the baseclass QWindow
like any other property during QML component creation, which would cause
create() to be called and the platform window would be created.
This left the 'visibility' of the QML window as Windowed, not respecting
the platform defaults for how windows should be shown. The user would
have to explicitly set "visibility: Window.AutomaticVisibility" for
this default to apply, which doesn't make sense -- it should be the
default.
We solve this by deferring setVisible and setVisibility on the window
until the component is complete and we have a full picture of its state.
We then ask the platform for the default state based on the window flags
(ensuring that eg "flags: Qt.Popup" will not result in maximized
windows on iOS and Android), and apply the deferred visibility.
The deferred visibility may still be 'false', but setting the window
state makes sense anyways, so that a later "visible = true" will
apply the default window state.
Deferring platform window creation until the geometry has been
potentially set from user code also has the benefit that the
platform window can check the geometry and apply a default
geometry if it's null. This was not possible when the 'visible'
property was a regular property, as you could not know if the
user's geometry changes would come after platform window creation.
Task-number: QTBUG-35174
Change-Id: Icf3236187992048a85b2196c059f9b54699041a4
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Reviewed-by: Robin Burchell <robin+qt@viroteck.net>
Reviewed-by: Gunnar Sletta <gunnar.sletta@digia.com>
Diffstat (limited to 'src/quick/items/qquickwindowmodule.cpp')
-rw-r--r-- | src/quick/items/qquickwindowmodule.cpp | 80 |
1 files changed, 79 insertions, 1 deletions
diff --git a/src/quick/items/qquickwindowmodule.cpp b/src/quick/items/qquickwindowmodule.cpp index b91edc2fd5..cd1b68991d 100644 --- a/src/quick/items/qquickwindowmodule.cpp +++ b/src/quick/items/qquickwindowmodule.cpp @@ -45,12 +45,50 @@ #include <QtCore/QCoreApplication> #include <QtQml/QQmlEngine> +#include <private/qguiapplication_p.h> +#include <private/qqmlengine_p.h> +#include <qpa/qplatformintegration.h> + QT_BEGIN_NAMESPACE class QQuickWindowQmlImpl : public QQuickWindow, public QQmlParserStatus { Q_INTERFACES(QQmlParserStatus) Q_OBJECT + + Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged) + Q_PROPERTY(Visibility visibility READ visibility WRITE setVisibility NOTIFY visibilityChanged) + +public: + QQuickWindowQmlImpl(QWindow *parent = 0) + : QQuickWindow(parent) + , m_complete(false) + , m_visible(isVisible()) + , m_visibility(AutomaticVisibility) + { + connect(this, &QWindow::visibleChanged, this, &QQuickWindowQmlImpl::visibleChanged); + connect(this, &QWindow::visibilityChanged, this, &QQuickWindowQmlImpl::visibilityChanged); + } + + void setVisible(bool visible) { + if (!m_complete) + m_visible = visible; + else + QQuickWindow::setVisible(visible); + } + + void setVisibility(Visibility visibility) + { + if (!m_complete) + m_visibility = visibility; + else + QQuickWindow::setVisibility(m_visibility); + } + +Q_SIGNALS: + void visibleChanged(bool arg); + void visibilityChanged(QWindow::Visibility visibility); + protected: void classBegin() { //Give QQuickView behavior when created from QML with QQmlApplicationEngine @@ -61,7 +99,47 @@ protected: } } - void componentComplete() {} + void componentComplete() { + m_complete = true; + + // We have deferred window creation until we have the full picture of what + // the user wanted in terms of window state, geometry, visibility, etc. + + if ((m_visibility == Hidden && m_visible) || (m_visibility > AutomaticVisibility && !m_visible)) { + QQmlData *data = QQmlData::get(this); + Q_ASSERT(data && data->context); + + QQmlError error; + error.setObject(this); + + const QQmlContextData* urlContext = data->context; + while (urlContext && urlContext->url.isEmpty()) + urlContext = urlContext->parent; + error.setUrl(urlContext ? urlContext->url : QUrl()); + + QString objectId = data->context->findObjectId(this); + if (!objectId.isEmpty()) + error.setDescription(QCoreApplication::translate("QQuickWindowQmlImpl", + "Conflicting properties 'visible' and 'visibility' for Window '%1'").arg(objectId)); + else + error.setDescription(QCoreApplication::translate("QQuickWindowQmlImpl", + "Conflicting properties 'visible' and 'visibility'")); + + QQmlEnginePrivate::get(data->context->engine)->warning(error); + } + + if (m_visibility == AutomaticVisibility) { + setWindowState(QGuiApplicationPrivate::platformIntegration()->defaultWindowState(flags())); + setVisible(m_visible); + } else { + setVisibility(m_visibility); + } + } + +private: + bool m_complete; + bool m_visible; + Visibility m_visibility; }; void QQuickWindowModule::defineModule() |