aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2014-03-03 15:40:24 +0100
committerSimon Hausmann <simon.hausmann@digia.com>2014-03-03 15:40:43 +0100
commit1511dc39a62e9d14b6755d6c2335547c85331d49 (patch)
tree0b60c51b7597b2fe4ea16a432f4c615214efa0a7 /src/quick/items
parent75b191b31d9936b134ca9776f1e69e891d03be11 (diff)
parent915dcb6f8cb6207566f4838f641f434508336fa7 (diff)
Merge remote-tracking branch 'origin/stable' into dev
This merge also removes the pin for qtbase. Change-Id: If86998fb912d100cfad150d255ed41544ba1fb0c
Diffstat (limited to 'src/quick/items')
-rw-r--r--src/quick/items/context2d/qquickcanvasitem.cpp2
-rw-r--r--src/quick/items/context2d/qquickcontext2dtexture.cpp6
-rw-r--r--src/quick/items/qquickdroparea.cpp9
-rw-r--r--src/quick/items/qquickflickable.cpp2
-rw-r--r--src/quick/items/qquickgridview.cpp10
-rw-r--r--src/quick/items/qquickgridview_p.h19
-rw-r--r--src/quick/items/qquickimage.cpp8
-rw-r--r--src/quick/items/qquickitemview.cpp6
-rw-r--r--src/quick/items/qquickitemview_p.h12
-rw-r--r--src/quick/items/qquickitemview_p_p.h2
-rw-r--r--src/quick/items/qquicklistview.cpp15
-rw-r--r--src/quick/items/qquicklistview_p.h16
-rw-r--r--src/quick/items/qquickrendercontrol.cpp30
-rw-r--r--src/quick/items/qquickrendercontrol_p.h1
-rw-r--r--src/quick/items/qquickshadereffect.cpp21
-rw-r--r--src/quick/items/qquickshadereffectsource.cpp12
-rw-r--r--src/quick/items/qquicktextinput.cpp27
-rw-r--r--src/quick/items/qquicktextinput_p_p.h1
-rw-r--r--src/quick/items/qquickwindow.cpp154
-rw-r--r--src/quick/items/qquickwindow.h12
-rw-r--r--src/quick/items/qquickwindow_p.h5
-rw-r--r--src/quick/items/qquickwindowmodule.cpp1
22 files changed, 279 insertions, 92 deletions
diff --git a/src/quick/items/context2d/qquickcanvasitem.cpp b/src/quick/items/context2d/qquickcanvasitem.cpp
index ed5c8d7bcb..17adf1b66b 100644
--- a/src/quick/items/context2d/qquickcanvasitem.cpp
+++ b/src/quick/items/context2d/qquickcanvasitem.cpp
@@ -640,6 +640,8 @@ void QQuickCanvasItem::updatePolish()
QQuickItem::updatePolish();
Q_D(QQuickCanvasItem);
+ if (!isVisible() && !(d->extra.isAllocated() && d->extra->effectRefCount>0))
+ return;
if (d->context && d->renderStrategy != QQuickCanvasItem::Cooperative)
d->context->prepare(d->canvasSize.toSize(), d->tileSize, d->canvasWindow.toRect(), d->dirtyRect.toRect(), d->smooth, antialiasing());
diff --git a/src/quick/items/context2d/qquickcontext2dtexture.cpp b/src/quick/items/context2d/qquickcontext2dtexture.cpp
index d3f2a956a3..ef1b65a04f 100644
--- a/src/quick/items/context2d/qquickcontext2dtexture.cpp
+++ b/src/quick/items/context2d/qquickcontext2dtexture.cpp
@@ -479,9 +479,9 @@ bool QQuickContext2DFBOTexture::doMultisampling() const
static bool multisamplingSupported = false;
if (!extensionsChecked) {
- QList<QByteArray> extensions = QByteArray((const char *)glGetString(GL_EXTENSIONS)).split(' ');
- multisamplingSupported = extensions.contains("GL_EXT_framebuffer_multisample")
- && extensions.contains("GL_EXT_framebuffer_blit");
+ const QSet<QByteArray> extensions = m_context->glContext()->extensions();
+ multisamplingSupported = extensions.contains(QByteArrayLiteral("GL_EXT_framebuffer_multisample"))
+ && extensions.contains(QByteArrayLiteral("GL_EXT_framebuffer_blit"));
extensionsChecked = true;
}
diff --git a/src/quick/items/qquickdroparea.cpp b/src/quick/items/qquickdroparea.cpp
index 8d58ffbfae..57e500a150 100644
--- a/src/quick/items/qquickdroparea.cpp
+++ b/src/quick/items/qquickdroparea.cpp
@@ -109,9 +109,6 @@ QQuickDropAreaPrivate::~QQuickDropAreaPrivate()
The \l drag.source property is communicated to the source of a drag event as
the recipient of a drop on the drag target.
-
- The \l delegate property provides a means to specify a component to be
- instantiated for each active drag over a drag target.
*/
QQuickDropArea::QQuickDropArea(QQuickItem *parent)
@@ -308,7 +305,7 @@ void QQuickDropArea::dragLeaveEvent(QDragLeaveEvent *)
/*!
\qmlsignal QtQuick::DropArea::onDropped(DragEvent drop)
- This handler is called when a drop event occurs within the bounds of a
+ This handler is called when a drop event occurs within the bounds of
a DropArea.
*/
@@ -383,8 +380,8 @@ void QQuickDropArea::dropEvent(QDropEvent *event)
The drop action may be one of:
\list
- \li Qt.CopyAction Copy the data to the target
- \li Qt.MoveAction Move the data from the source to the target
+ \li Qt.CopyAction Copy the data to the target.
+ \li Qt.MoveAction Move the data from the source to the target.
\li Qt.LinkAction Create a link from the source to the target.
\li Qt.IgnoreAction Ignore the action (do nothing with the data).
\endlist
diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp
index 789d1952c0..2f2c932db5 100644
--- a/src/quick/items/qquickflickable.cpp
+++ b/src/quick/items/qquickflickable.cpp
@@ -1262,6 +1262,8 @@ void QQuickFlickable::wheelEvent(QWheelEvent *event)
return;
}
+ event->setAccepted(false);
+
int yDelta = event->angleDelta().y();
int xDelta = event->angleDelta().x();
if (yflick() && yDelta != 0) {
diff --git a/src/quick/items/qquickgridview.cpp b/src/quick/items/qquickgridview.cpp
index 8587da5ac3..f97229a76a 100644
--- a/src/quick/items/qquickgridview.cpp
+++ b/src/quick/items/qquickgridview.cpp
@@ -65,8 +65,8 @@ QT_BEGIN_NAMESPACE
class FxGridItemSG : public FxViewItem
{
public:
- FxGridItemSG(QQuickItem *i, QQuickGridView *v, bool own) : FxViewItem(i, v, own), view(v) {
- attached = static_cast<QQuickGridViewAttached*>(qmlAttachedPropertiesObject<QQuickGridView>(item));
+ FxGridItemSG(QQuickItem *i, QQuickGridView *v, bool own) : FxViewItem(i, v, own, static_cast<QQuickItemViewAttached*>(qmlAttachedPropertiesObject<QQuickGridView>(i))), view(v)
+ {
}
qreal position() const {
@@ -1283,7 +1283,8 @@ void QQuickGridView::setHighlightFollowsCurrentItem(bool autoHighlight)
\qmlattachedproperty GridView QtQuick::GridView::view
This attached property holds the view that manages this delegate instance.
- It is attached to each instance of the delegate.
+ It is attached to each instance of the delegate and also to the header, the footer
+ and the highlight delegates.
\snippet qml/gridview/gridview.qml isCurrentItem
*/
@@ -2127,6 +2128,9 @@ void QQuickGridView::geometryChanged(const QRectF &newGeometry, const QRectF &ol
void QQuickGridView::initItem(int index, QObject *obj)
{
QQuickItemView::initItem(index, obj);
+
+ // setting the view from the FxViewItem wrapper is too late if the delegate
+ // needs access to the view in Component.onCompleted
QQuickItem *item = qmlobject_cast<QQuickItem*>(obj);
if (item) {
QQuickGridViewAttached *attached = static_cast<QQuickGridViewAttached *>(
diff --git a/src/quick/items/qquickgridview_p.h b/src/quick/items/qquickgridview_p.h
index 8f41f39919..ff0e2217fa 100644
--- a/src/quick/items/qquickgridview_p.h
+++ b/src/quick/items/qquickgridview_p.h
@@ -42,8 +42,6 @@
#ifndef QQUICKGRIDVIEW_P_H
#define QQUICKGRIDVIEW_P_H
-#include <QtCore/qpointer.h>
-
#include "qquickitemview_p.h"
@@ -118,23 +116,8 @@ class QQuickGridViewAttached : public QQuickItemViewAttached
Q_OBJECT
public:
QQuickGridViewAttached(QObject *parent)
- : QQuickItemViewAttached(parent), m_view(0) {}
+ : QQuickItemViewAttached(parent) {}
~QQuickGridViewAttached() {}
-
- Q_PROPERTY(QQuickGridView *view READ view NOTIFY viewChanged)
- QQuickGridView *view() { return m_view; }
- void setView(QQuickGridView *view) {
- if (view != m_view) {
- m_view = view;
- Q_EMIT viewChanged();
- }
- }
-
-Q_SIGNALS:
- void viewChanged();
-
-public:
- QPointer<QQuickGridView> m_view;
};
diff --git a/src/quick/items/qquickimage.cpp b/src/quick/items/qquickimage.cpp
index b6b8a2a39b..69a39d2396 100644
--- a/src/quick/items/qquickimage.cpp
+++ b/src/quick/items/qquickimage.cpp
@@ -676,6 +676,14 @@ QSGNode *QQuickImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
sourceRect.width() / d->pix.width(),
sourceRect.height() / d->pix.height());
+ if (targetRect.isEmpty()
+ || !qIsFinite(targetRect.width()) || !qIsFinite(targetRect.height())
+ || nsrect.isEmpty()
+ || !qIsFinite(nsrect.width()) || !qIsFinite(nsrect.height())) {
+ delete node;
+ return 0;
+ }
+
if (d->pixmapChanged) {
// force update the texture in the node to trigger reconstruction of
// geometry and the likes when a atlas segment has changed.
diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp
index 30d0619f7a..020d48613b 100644
--- a/src/quick/items/qquickitemview.cpp
+++ b/src/quick/items/qquickitemview.cpp
@@ -51,15 +51,17 @@ QT_BEGIN_NAMESPACE
#define QML_VIEW_DEFAULTCACHEBUFFER 320
#endif
-FxViewItem::FxViewItem(QQuickItem *i, QQuickItemView *v, bool own)
+FxViewItem::FxViewItem(QQuickItem *i, QQuickItemView *v, bool own, QQuickItemViewAttached *attached)
: item(i)
, view(v)
, transitionableItem(0)
- , attached(0)
+ , attached(attached)
, ownItem(own)
, releaseAfterTransition(false)
, trackGeom(false)
{
+ if (attached) // can be null for default components (see createComponentItem)
+ attached->setView(view);
}
FxViewItem::~FxViewItem()
diff --git a/src/quick/items/qquickitemview_p.h b/src/quick/items/qquickitemview_p.h
index ad026a3152..57635d7780 100644
--- a/src/quick/items/qquickitemview_p.h
+++ b/src/quick/items/qquickitemview_p.h
@@ -43,6 +43,7 @@
#define QQUICKITEMVIEW_P_H
#include "qquickflickable_p.h"
+#include <qpointer.h>
QT_BEGIN_NAMESPACE
@@ -282,6 +283,7 @@ class Q_AUTOTEST_EXPORT QQuickItemViewAttached : public QObject
{
Q_OBJECT
+ Q_PROPERTY(QQuickItemView *view READ view NOTIFY viewChanged)
Q_PROPERTY(bool isCurrentItem READ isCurrentItem NOTIFY currentItemChanged)
Q_PROPERTY(bool delayRemove READ delayRemove WRITE setDelayRemove NOTIFY delayRemoveChanged)
@@ -294,6 +296,14 @@ public:
: QObject(parent), m_isCurrent(false), m_delayRemove(false) {}
~QQuickItemViewAttached() {}
+ QQuickItemView *view() { return m_view; }
+ void setView(QQuickItemView *view) {
+ if (view != m_view) {
+ m_view = view;
+ Q_EMIT viewChanged();
+ }
+ }
+
bool isCurrentItem() const { return m_isCurrent; }
void setIsCurrentItem(bool c) {
if (m_isCurrent != c) {
@@ -353,6 +363,7 @@ public:
void emitRemove() { Q_EMIT remove(); }
Q_SIGNALS:
+ void viewChanged();
void currentItemChanged();
void delayRemoveChanged();
@@ -364,6 +375,7 @@ Q_SIGNALS:
void nextSectionChanged();
public:
+ QPointer<QQuickItemView> m_view;
bool m_isCurrent : 1;
bool m_delayRemove : 1;
diff --git a/src/quick/items/qquickitemview_p_p.h b/src/quick/items/qquickitemview_p_p.h
index af7c23c02e..a0d17b3bf9 100644
--- a/src/quick/items/qquickitemview_p_p.h
+++ b/src/quick/items/qquickitemview_p_p.h
@@ -56,7 +56,7 @@ QT_BEGIN_NAMESPACE
class FxViewItem
{
public:
- FxViewItem(QQuickItem *, QQuickItemView *, bool own);
+ FxViewItem(QQuickItem *, QQuickItemView *, bool own, QQuickItemViewAttached *attached);
virtual ~FxViewItem();
qreal itemX() const;
diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp
index 2dd61e386f..3ac28f438b 100644
--- a/src/quick/items/qquicklistview.cpp
+++ b/src/quick/items/qquicklistview.cpp
@@ -247,16 +247,14 @@ void QQuickViewSection::setLabelPositioning(int l)
class FxListItemSG : public FxViewItem
{
public:
- FxListItemSG(QQuickItem *i, QQuickListView *v, bool own) : FxViewItem(i, v, own), view(v) {
- attached = static_cast<QQuickListViewAttached*>(qmlAttachedPropertiesObject<QQuickListView>(item));
+ FxListItemSG(QQuickItem *i, QQuickListView *v, bool own) : FxViewItem(i, v, own, static_cast<QQuickItemViewAttached*>(qmlAttachedPropertiesObject<QQuickListView>(i))), view(v)
+ {
}
inline QQuickItem *section() const {
return attached ? static_cast<QQuickListViewAttached*>(attached)->m_sectionItem : 0;
}
void setSection(QQuickItem *s) {
- if (!attached)
- attached = static_cast<QQuickListViewAttached*>(qmlAttachedPropertiesObject<QQuickListView>(item));
static_cast<QQuickListViewAttached*>(attached)->m_sectionItem = s;
}
@@ -972,6 +970,9 @@ QQuickItem * QQuickListViewPrivate::getSectionItem(const QString &section)
QQml_setParent_noEvent(sectionItem, contentItem);
sectionItem->setParentItem(contentItem);
}
+ // sections are not controlled by FxListItemSG, so apply attached properties here
+ QQuickItemViewAttached *attached = static_cast<QQuickItemViewAttached*>(qmlAttachedPropertiesObject<QQuickListView>(sectionItem));
+ attached->setView(q);
} else {
delete context;
}
@@ -1787,7 +1788,8 @@ QQuickListView::~QQuickListView()
\qmlattachedproperty ListView QtQuick::ListView::view
This attached property holds the view that manages this delegate instance.
- It is attached to each instance of the delegate.
+ It is attached to each instance of the delegate and also to the header, the footer,
+ the section and the highlight delegates.
*/
/*!
@@ -2855,6 +2857,9 @@ void QQuickListView::geometryChanged(const QRectF &newGeometry, const QRectF &ol
void QQuickListView::initItem(int index, QObject *object)
{
QQuickItemView::initItem(index, object);
+
+ // setting the view from the FxViewItem wrapper is too late if the delegate
+ // needs access to the view in Component.onCompleted
QQuickItem *item = qmlobject_cast<QQuickItem*>(object);
if (item) {
QQuickListViewAttached *attached = static_cast<QQuickListViewAttached *>(
diff --git a/src/quick/items/qquicklistview_p.h b/src/quick/items/qquicklistview_p.h
index b00501d274..2494e101cd 100644
--- a/src/quick/items/qquicklistview_p.h
+++ b/src/quick/items/qquicklistview_p.h
@@ -43,7 +43,6 @@
#define QQUICKLISTVIEW_P_H
#include "qquickitemview_p.h"
-#include <qpointer.h>
QT_BEGIN_NAMESPACE
@@ -175,23 +174,10 @@ class QQuickListViewAttached : public QQuickItemViewAttached
public:
QQuickListViewAttached(QObject *parent)
- : QQuickItemViewAttached(parent), m_view(0), m_sectionItem(0) {}
+ : QQuickItemViewAttached(parent), m_sectionItem(0) {}
~QQuickListViewAttached() {}
- Q_PROPERTY(QQuickListView *view READ view NOTIFY viewChanged)
- QQuickListView *view() { return m_view; }
- void setView(QQuickListView *view) {
- if (view != m_view) {
- m_view = view;
- Q_EMIT viewChanged();
- }
- }
-
-Q_SIGNALS:
- void viewChanged();
-
public:
- QPointer<QQuickListView> m_view;
QQuickItem *m_sectionItem;
};
diff --git a/src/quick/items/qquickrendercontrol.cpp b/src/quick/items/qquickrendercontrol.cpp
index 7e4335ba63..16ed6f0e10 100644
--- a/src/quick/items/qquickrendercontrol.cpp
+++ b/src/quick/items/qquickrendercontrol.cpp
@@ -114,9 +114,13 @@ void QQuickRenderControl::initialize(QOpenGLContext *gl)
Q_D(QQuickRenderControl);
if (!d->window)
return;
- bool current = gl->makeCurrent(d->window);
- if (current)
- QQuickWindowPrivate::get(d->window)->context->initialize(gl);
+
+ // It is the caller's responsiblity to make a context/surface current.
+ // It cannot be done here since the surface to use may not be the
+ // surface belonging to window. In fact window may not have a native
+ // window/surface at all.
+
+ QQuickWindowPrivate::get(d->window)->context->initialize(gl);
}
void QQuickRenderControl::invalidate()
@@ -158,6 +162,26 @@ bool QQuickRenderControl::sync()
}
/*!
+ Stop rendering and release resources. This function is typically
+ called when the window is hidden. Requires a current context.
+ */
+void QQuickRenderControl::stop()
+{
+ Q_D(QQuickRenderControl);
+ if (!d->window)
+ return;
+
+ QQuickWindowPrivate *cd = QQuickWindowPrivate::get(d->window);
+ cd->fireAboutToStop();
+ cd->cleanupNodesOnShutdown();
+
+ if (!cd->persistentSceneGraph) {
+ d->rc->invalidate();
+ QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
+ }
+}
+
+/*!
Render the scenegraph using the current context.
*/
void QQuickRenderControl::render()
diff --git a/src/quick/items/qquickrendercontrol_p.h b/src/quick/items/qquickrendercontrol_p.h
index 7255a9ae0b..98dc946303 100644
--- a/src/quick/items/qquickrendercontrol_p.h
+++ b/src/quick/items/qquickrendercontrol_p.h
@@ -71,6 +71,7 @@ public:
void polishItems();
void render();
bool sync();
+ void stop();
QImage grab();
diff --git a/src/quick/items/qquickshadereffect.cpp b/src/quick/items/qquickshadereffect.cpp
index 9a20703f18..e57b7abddc 100644
--- a/src/quick/items/qquickshadereffect.cpp
+++ b/src/quick/items/qquickshadereffect.cpp
@@ -478,6 +478,19 @@ void QQuickShaderEffectCommon::sourceDestroyed(QObject *object)
}
}
+static bool qquick_uniqueInUniformData(QQuickItem *source, const QVector<QQuickShaderEffectMaterial::UniformData> *uniformData, int typeToSkip, int indexToSkip)
+{
+ for (int s=0; s<QQuickShaderEffectMaterialKey::ShaderTypeCount; ++s) {
+ for (int i=0; i<uniformData[s].size(); ++i) {
+ if (s == typeToSkip && i == indexToSkip)
+ continue;
+ const QQuickShaderEffectMaterial::UniformData &d = uniformData[s][i];
+ if (d.specialType == QQuickShaderEffectMaterial::UniformData::Sampler && qvariant_cast<QObject *>(d.value) == source)
+ return false;
+ }
+ }
+ return true;
+}
void QQuickShaderEffectCommon::propertyChanged(QQuickItem *item, int mappedId,
bool *textureProviderChanged)
@@ -490,7 +503,13 @@ void QQuickShaderEffectCommon::propertyChanged(QQuickItem *item, int mappedId,
if (source) {
if (item->window())
QQuickItemPrivate::get(source)->derefWindow();
- QObject::disconnect(source, SIGNAL(destroyed(QObject*)), item, SLOT(sourceDestroyed(QObject*)));
+
+ // QObject::disconnect() will disconnect all matching connections. If the same
+ // source has been attached to two separate samplers, then changing one of them
+ // would trigger both to be disconnected. Without the connection we'll end up
+ // with a dangling pointer in the uniformData.
+ if (qquick_uniqueInUniformData(source, uniformData, shaderType, index))
+ QObject::disconnect(source, SIGNAL(destroyed(QObject*)), item, SLOT(sourceDestroyed(QObject*)));
}
d.value = item->property(d.name.constData());
diff --git a/src/quick/items/qquickshadereffectsource.cpp b/src/quick/items/qquickshadereffectsource.cpp
index 98203c51e5..ebeff599f4 100644
--- a/src/quick/items/qquickshadereffectsource.cpp
+++ b/src/quick/items/qquickshadereffectsource.cpp
@@ -353,9 +353,9 @@ void QQuickShaderEffectTexture::grab()
if (m_context->openglContext()->format().samples() <= 1) {
m_multisampling = false;
} else {
- QList<QByteArray> extensions = QByteArray((const char *)glGetString(GL_EXTENSIONS)).split(' ');
- m_multisampling = extensions.contains("GL_EXT_framebuffer_multisample")
- && extensions.contains("GL_EXT_framebuffer_blit");
+ const QSet<QByteArray> extensions = m_context->openglContext()->extensions();
+ m_multisampling = extensions.contains(QByteArrayLiteral("GL_EXT_framebuffer_multisample"))
+ && extensions.contains(QByteArrayLiteral("GL_EXT_framebuffer_blit"));
}
m_multisamplingChecked = true;
}
@@ -622,6 +622,8 @@ void QQuickShaderEffectSource::ensureTexture()
connect(m_texture, SIGNAL(scheduledUpdateCompleted()), this, SIGNAL(scheduledUpdateCompleted()));
}
+static void get_wrap_mode(QQuickShaderEffectSource::WrapMode mode, QSGTexture::WrapMode *hWrap, QSGTexture::WrapMode *vWrap);
+
QSGTextureProvider *QQuickShaderEffectSource::textureProvider() const
{
const QQuickItemPrivate *d = QQuickItemPrivate::get(this);
@@ -634,6 +636,10 @@ QSGTextureProvider *QQuickShaderEffectSource::textureProvider() const
const_cast<QQuickShaderEffectSource *>(this)->m_provider = new QQuickShaderEffectSourceTextureProvider();
const_cast<QQuickShaderEffectSource *>(this)->ensureTexture();
connect(m_texture, SIGNAL(updateRequested()), m_provider, SIGNAL(textureChanged()));
+
+ get_wrap_mode(m_wrapMode, &m_provider->horizontalWrap, &m_provider->verticalWrap);
+ m_provider->mipmapFiltering = mipmap() ? QSGTexture::Linear : QSGTexture::None;
+ m_provider->filtering = smooth() ? QSGTexture::Linear : QSGTexture::Nearest;
m_provider->sourceTexture = m_texture;
}
return m_provider;
diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp
index 7ee1c937c6..ad79f0eadf 100644
--- a/src/quick/items/qquicktextinput.cpp
+++ b/src/quick/items/qquicktextinput.cpp
@@ -1710,6 +1710,8 @@ void QQuickTextInput::geometryChanged(const QRectF &newGeometry,
if (!d->inLayout) {
if (newGeometry.width() != oldGeometry.width())
d->updateLayout();
+ else if (newGeometry.height() != oldGeometry.height() && d->vAlign != QQuickTextInput::AlignTop)
+ d->updateBaselineOffset();
updateCursorRectangle();
}
QQuickImplicitSizeItem::geometryChanged(newGeometry, oldGeometry);
@@ -2855,20 +2857,33 @@ void QQuickTextInputPrivate::updateLayout()
else
q->setImplicitHeight(height);
+ updateBaselineOffset();
+ if (previousSize != contentSize)
+ emit q->contentSizeChanged();
+}
+
+/*!
+ \internal
+ \brief QQuickTextInputPrivate::updateBaselineOffset
+
+ Assumes contentSize.height() is already calculated.
+ */
+void QQuickTextInputPrivate::updateBaselineOffset()
+{
+ Q_Q(QQuickTextInput);
+ if (!q->isComponentComplete())
+ return;
QFontMetricsF fm(font);
qreal yoff = 0;
if (q->heightValid()) {
- const qreal itemHeight = q->height();
+ const qreal surplusHeight = q->height() - contentSize.height();
if (vAlign == QQuickTextInput::AlignBottom)
- yoff = itemHeight - height;
+ yoff = surplusHeight;
else if (vAlign == QQuickTextInput::AlignVCenter)
- yoff = (itemHeight - height)/2;
+ yoff = surplusHeight/2;
}
q->setBaselineOffset(fm.ascent() + yoff);
-
- if (previousSize != contentSize)
- emit q->contentSizeChanged();
}
#ifndef QT_NO_CLIPBOARD
diff --git a/src/quick/items/qquicktextinput_p_p.h b/src/quick/items/qquicktextinput_p_p.h
index 240fc7a599..21bd1bd6d7 100644
--- a/src/quick/items/qquicktextinput_p_p.h
+++ b/src/quick/items/qquicktextinput_p_p.h
@@ -423,6 +423,7 @@ public:
void setCursorBlinkPeriod(int msec);
void updateLayout();
+ void updateBaselineOffset();
qreal getImplicitWidth() const;
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index f035e87d99..bbc4e8b55c 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -216,9 +216,11 @@ void QQuickWindow::exposeEvent(QExposeEvent *)
}
/*! \reimp */
-void QQuickWindow::resizeEvent(QResizeEvent *)
+void QQuickWindow::resizeEvent(QResizeEvent *ev)
{
Q_D(QQuickWindow);
+ if (d->contentItem)
+ d->contentItem->setSize(ev->size());
if (d->windowManager)
d->windowManager->resize(this);
}
@@ -258,23 +260,16 @@ void QQuickWindowPrivate::polishItems()
{
int maxPolishCycles = 100000;
- int removedItems;
- do {
- removedItems = 0;
+ while (!itemsToPolish.isEmpty() && --maxPolishCycles > 0) {
QSet<QQuickItem *> itms = itemsToPolish;
+ itemsToPolish.clear();
for (QSet<QQuickItem *>::iterator it = itms.begin(); it != itms.end(); ++it) {
QQuickItem *item = *it;
- QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
-
- if (item->isVisible() || (itemPrivate->extra.isAllocated() && itemPrivate->extra->effectRefCount>0)) {
- itemPrivate->polishScheduled = false;
- itemsToPolish.remove(item);
- item->updatePolish();
- ++removedItems;
- }
+ QQuickItemPrivate::get(item)->polishScheduled = false;
+ item->updatePolish();
}
- } while (removedItems > 0 && --maxPolishCycles > 0);
+ }
if (maxPolishCycles == 0)
qWarning("QQuickWindow: possible QQuickItem::polish() loop");
@@ -360,6 +355,8 @@ void QQuickWindowPrivate::syncSceneGraph()
renderer->setClearMode(mode);
renderer->setCustomRenderMode(customRenderMode);
+
+ emit q->afterSynchronizing();
context->endSync();
}
@@ -368,6 +365,9 @@ void QQuickWindowPrivate::renderSceneGraph(const QSize &size)
{
QML_MEMORY_SCOPE_STRING("SceneGraph");
Q_Q(QQuickWindow);
+ if (!renderer)
+ return;
+
animationController->advance();
emit q->beforeRendering();
int fboId = 0;
@@ -435,6 +435,7 @@ void QQuickWindowPrivate::init(QQuickWindow *c, QQuickRenderControl *control)
contentItemPrivate->window = q;
contentItemPrivate->windowRefCount = 1;
contentItemPrivate->flags |= QQuickItem::ItemIsFocusScope;
+ contentItem->setSize(q->size());
customRenderMode = qgetenv("QSG_VISUALIZE");
renderControl = control;
@@ -476,24 +477,12 @@ void QQuickWindowPrivate::init(QQuickWindow *c, QQuickRenderControl *control)
QQmlListProperty<QObject> QQuickWindowPrivate::data()
{
- initContentItem();
return QQmlListProperty<QObject>(q_func(), 0, QQuickWindowPrivate::data_append,
QQuickWindowPrivate::data_count,
QQuickWindowPrivate::data_at,
QQuickWindowPrivate::data_clear);
}
-void QQuickWindowPrivate::initContentItem()
-{
- Q_Q(QQuickWindow);
- q->connect(q, SIGNAL(widthChanged(int)),
- contentItem, SLOT(setWidth(int)));
- q->connect(q, SIGNAL(heightChanged(int)),
- contentItem, SLOT(setHeight(int)));
- contentItem->setWidth(q->width());
- contentItem->setHeight(q->height());
-}
-
static QMouseEvent *touchToMouseEvent(QEvent::Type type, const QTouchEvent::TouchPoint &p, QTouchEvent *event, QQuickItem *item, bool transformNeeded = true)
{
// The touch point local position and velocity are not yet transformed.
@@ -2679,6 +2668,17 @@ void QQuickWindowPrivate::updateDirtyNode(QQuickItem *item)
}
+bool QQuickWindowPrivate::emitError(QQuickWindow::SceneGraphError error, const QString &msg)
+{
+ Q_Q(QQuickWindow);
+ static const QMetaMethod errorSignal = QMetaMethod::fromSignal(&QQuickWindow::sceneGraphError);
+ if (q->isSignalConnected(errorSignal)) {
+ emit q->sceneGraphError(error, msg);
+ return true;
+ }
+ return false;
+}
+
void QQuickWindow::maybeUpdate()
{
Q_D(QQuickWindow);
@@ -2754,6 +2754,21 @@ QOpenGLContext *QQuickWindow::openglContext() const
*/
/*!
+ \fn void QQuickWindow::sceneGraphError(SceneGraphError error, const QString &message)
+
+ This signal is emitted when an error occurred during scene graph initialization.
+
+ Applications should connect to this signal if they wish to handle errors,
+ like OpenGL context creation failures, in a custom way. When no slot is
+ connected to the signal, the behavior will be different: Quick will print
+ the message, or show a message box, and terminate the application.
+
+ This signal will be emitted from the gui thread.
+
+ \since 5.3
+ */
+
+/*!
\class QQuickCloseEvent
\internal
\since 5.1
@@ -2987,6 +3002,20 @@ QQmlIncubationController *QQuickWindow::incubationController() const
*/
/*!
+ \enum QQuickWindow::SceneGraphError
+
+ This enum describes the error in a sceneGraphError() signal.
+
+ \value ContextNotAvailable OpenGL context creation failed. This typically means that
+ no suitable OpenGL implementation was found, for example because no graphics drivers
+ are installed and so no OpenGL 2 support is present. On mobile and embedded boards
+ that use OpenGL ES such an error is likely to indicate issues in the windowing system
+ integration and possibly an incorrect configuration of Qt.
+
+ \since 5.3
+ */
+
+/*!
\fn void QQuickWindow::beforeSynchronizing()
This signal is emitted before the scene graph is synchronized with the QML state.
@@ -3006,6 +3035,27 @@ QQmlIncubationController *QQuickWindow::incubationController() const
*/
/*!
+ \fn void QQuickWindow::afterSynchronizing()
+
+ This signal is emitted after the scene graph is synchronized with the QML state.
+
+ This signal can be used to do preparation required after calls to
+ QQuickItem::updatePaintNode(), while the GUI thread is still locked.
+
+ The GL context used for rendering the scene graph will be bound at this point.
+
+ \warning This signal is emitted from the scene graph rendering thread. If your
+ slot function needs to finish before execution continues, you must make sure that
+ the connection is direct (see Qt::ConnectionType).
+
+ \warning Make very sure that a signal handler for afterSynchronizing leaves the GL
+ context in the same state as it was when the signal handler was entered. Failing to
+ do so can result in the scene not rendering properly.
+
+ \since 5.3
+ */
+
+/*!
\fn void QQuickWindow::beforeRendering()
This signal is emitted before the scene starts rendering.
@@ -3044,6 +3094,60 @@ QQmlIncubationController *QQuickWindow::incubationController() const
do so can result in the scene not rendering properly.
*/
+/*!
+ \fn void QQuickWindow::afterAnimating()
+
+ This signal is emitted on the gui thread before requesting the render thread to
+ perform the synchronization of the scene graph.
+
+ Unlike the other similar signals, this one is emitted on the gui thread instead
+ of the render thread. It can be used to synchronize external animation systems
+ with the QML content.
+
+ \since 5.3
+ */
+
+/*!
+ \fn void QQuickWindow::openglContextCreated(QOpenGLContext *context)
+
+ This signal is emitted on the gui thread when the OpenGL \a context
+ for this window is created, before it is made current.
+
+ Some implementations will share the same OpenGL context between
+ multiple QQuickWindow instances. The openglContextCreated() signal
+ will in this case only be emitted for the first window, when the
+ OpenGL context is actually created.
+
+ QQuickWindow::openglContext() will still return 0 for this window
+ until after the QQuickWindow::sceneGraphInitialize() has been
+ emitted.
+
+ \since 5.3
+ */
+
+/*!
+ \fn void QQuickWindow::sceneGraphAboutToStop()
+
+ This signal is emitted on the render thread when the scene graph is
+ about to stop rendering. This happens usually because the window
+ has been hidden.
+
+ Applications may use this signal to release resources, but should be
+ prepared to reinstantiated them again fast. The scene graph and the
+ OpenGL context are not released at this time.
+
+ \warning This signal is emitted from the scene graph rendering thread. If your
+ slot function needs to finish before execution continues, you must make sure that
+ the connection is direct (see Qt::ConnectionType).
+
+ \warning Make very sure that a signal handler for afterRendering() leaves the GL
+ context in the same state as it was when the signal handler was entered. Failing to
+ do so can result in the scene not rendering properly.
+
+ \sa scenegraphInvalidated()
+
+ \since 5.3
+ */
/*!
diff --git a/src/quick/items/qquickwindow.h b/src/quick/items/qquickwindow.h
index 233340d6fa..2572f31375 100644
--- a/src/quick/items/qquickwindow.h
+++ b/src/quick/items/qquickwindow.h
@@ -79,6 +79,11 @@ public:
Q_DECLARE_FLAGS(CreateTextureOptions, CreateTextureOption)
+ enum SceneGraphError {
+ ContextNotAvailable = 1
+ };
+ Q_ENUMS(SceneGraphError)
+
QQuickWindow(QWindow *parent = 0);
virtual ~QQuickWindow();
@@ -133,14 +138,21 @@ public:
Q_SIGNALS:
void frameSwapped();
+ Q_REVISION(2) void openglContextCreated(QOpenGLContext *context);
void sceneGraphInitialized();
void sceneGraphInvalidated();
void beforeSynchronizing();
+ Q_REVISION(2) void afterSynchronizing();
void beforeRendering();
void afterRendering();
+ Q_REVISION(2) void afterAnimating();
+ Q_REVISION(2) void sceneGraphAboutToStop();
+
Q_REVISION(1) void closing(QQuickCloseEvent *close);
void colorChanged(const QColor &);
Q_REVISION(1) void activeFocusItemChanged();
+ Q_REVISION(2) void sceneGraphError(QQuickWindow::SceneGraphError error, const QString &message);
+
public Q_SLOTS:
void update();
diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h
index 5f61403a40..8b6073c30a 100644
--- a/src/quick/items/qquickwindow_p.h
+++ b/src/quick/items/qquickwindow_p.h
@@ -105,7 +105,6 @@ public:
virtual ~QQuickWindowPrivate();
void init(QQuickWindow *, QQuickRenderControl *control = 0);
- void initContentItem();//Currently only used if items added in QML
QQuickRootItem *contentItem;
QSet<QQuickItem *> parentlessItems;
@@ -184,6 +183,8 @@ public:
bool isRenderable() const;
+ bool emitError(QQuickWindow::SceneGraphError error, const QString &msg);
+
QQuickItem::UpdatePaintNodeData updatePaintNodeData;
QQuickItem *dirtyItemList;
@@ -199,6 +200,8 @@ public:
void updateDirtyNode(QQuickItem *);
void fireFrameSwapped() { Q_EMIT q_func()->frameSwapped(); }
+ void fireOpenGLContextCreated(QOpenGLContext *context) { Q_EMIT q_func()->openglContextCreated(context); }
+ void fireAboutToStop() { Q_EMIT q_func()->sceneGraphAboutToStop(); }
QSGRenderContext *context;
QSGRenderer *renderer;
diff --git a/src/quick/items/qquickwindowmodule.cpp b/src/quick/items/qquickwindowmodule.cpp
index 44a4bf3db6..f6c32dcac3 100644
--- a/src/quick/items/qquickwindowmodule.cpp
+++ b/src/quick/items/qquickwindowmodule.cpp
@@ -149,6 +149,7 @@ void QQuickWindowModule::defineModule()
qmlRegisterType<QQuickWindow>(uri, 2, 0, "Window");
qmlRegisterRevision<QWindow,1>(uri, 2, 1);
qmlRegisterRevision<QQuickWindow,1>(uri, 2, 1);//Type moved to a subclass, but also has new members
+ qmlRegisterRevision<QQuickWindow,2>(uri, 2, 2);
qmlRegisterType<QQuickWindowQmlImpl>(uri, 2, 1, "Window");
qmlRegisterUncreatableType<QQuickScreen>(uri, 2, 0, "Screen", QStringLiteral("Screen can only be used via the attached property."));
}