Merge remote-tracking branch 'origin/5.6' into 5.7

Conflicts:
	src/quick/items/qquickwindow.cpp
	tests/auto/quick/qquicktext/BLACKLIST
	tests/auto/quick/qquicktextedit/BLACKLIST

Change-Id: I8bd68b0b5e853b7908791d2cbddd18dd527c76ae
This commit is contained in:
Liang Qi 2016-10-27 09:54:43 +02:00
commit 6b58ce5251
17 changed files with 82 additions and 46 deletions

View File

@ -62,7 +62,7 @@ FocusScope {
text: "Enter word" text: "Enter word"
font.pixelSize: 18 font.pixelSize: 18
color: "#707070" color: "#707070"
opacity: input.length ? 0 : 1 opacity: input.displayText.length ? 0 : 1
} }
Text { Text {

View File

@ -52,8 +52,8 @@ remain with C++ by invoking QQmlEngine::setObjectOwnership() with
QQmlEngine::CppOwnership specified. QQmlEngine::CppOwnership specified.
Additionally, the QML engine respects the normal QObject parent ownership Additionally, the QML engine respects the normal QObject parent ownership
semantics of Qt C++ objects, and will not ever take ownership of a QObject semantics of Qt C++ objects, and will never delete a QObject instance which
instance which already has a parent. has a parent.
\section1 Basic Qt Data Types \section1 Basic Qt Data Types

View File

@ -971,7 +971,7 @@ void InstructionSelection::swapValues(IR::Expr *source, IR::Expr *target)
tag = QV4::Value::Integer_Type_Internal; tag = QV4::Value::Integer_Type_Internal;
break; break;
default: default:
tag = QV4::Value::Undefined_Type; tag = 31337; // bogus value
Q_UNREACHABLE(); Q_UNREACHABLE();
} }
_as->store32(Assembler::TrustedImm32(tag), addr); _as->store32(Assembler::TrustedImm32(tag), addr);
@ -1418,7 +1418,7 @@ void InstructionSelection::visitCJump(IR::CJump *s)
Address temp = _as->loadAddress(Assembler::ScratchRegister, s->cond); Address temp = _as->loadAddress(Assembler::ScratchRegister, s->cond);
Address tag = temp; Address tag = temp;
tag.offset += QV4::Value::tagOffset(); tag.offset += QV4::Value::tagOffset();
Assembler::Jump booleanConversion = _as->branch32(Assembler::NotEqual, tag, Assembler::TrustedImm32(QV4::Value::Boolean_Type)); Assembler::Jump booleanConversion = _as->branch32(Assembler::NotEqual, tag, Assembler::TrustedImm32(QV4::Value::Boolean_Type_Internal));
Address data = temp; Address data = temp;
data.offset += QV4::Value::valueOffset(); data.offset += QV4::Value::valueOffset();
@ -1582,7 +1582,7 @@ void InstructionSelection::visitRet(IR::Ret *s)
tag = QV4::Value::Boolean_Type_Internal; tag = QV4::Value::Boolean_Type_Internal;
break; break;
default: default:
tag = QV4::Value::Undefined_Type; tag = 31337; // bogus value
Q_UNREACHABLE(); Q_UNREACHABLE();
} }
_as->or64(Assembler::TrustedImm64(tag << 32), _as->or64(Assembler::TrustedImm64(tag << 32),

View File

@ -104,7 +104,7 @@ Q_STATIC_ASSERT(sizeof(Heap::ArrayData) == sizeof(Heap::SparseArrayData));
static Q_ALWAYS_INLINE void storeValue(ReturnedValue *target, uint value) static Q_ALWAYS_INLINE void storeValue(ReturnedValue *target, uint value)
{ {
Value v; Value v;
v.setTagValue(Value::fromReturnedValue(*target).tag(), value); v.setEmpty(value);
*target = v.asReturnedValue(); *target = v.asReturnedValue();
} }
@ -193,6 +193,7 @@ void ArrayData::realloc(Object *o, Type newType, uint requested, bool enforceAtt
} else { } else {
sparse->sparse = new SparseArray; sparse->sparse = new SparseArray;
lastFree = &sparse->freeList; lastFree = &sparse->freeList;
storeValue(lastFree, 0);
for (uint i = 0; i < toCopy; ++i) { for (uint i = 0; i < toCopy; ++i) {
if (!sparse->arrayData[i].isEmpty()) { if (!sparse->arrayData[i].isEmpty()) {
SparseArrayNode *n = sparse->sparse->insert(i); SparseArrayNode *n = sparse->sparse->insert(i);
@ -213,6 +214,8 @@ void ArrayData::realloc(Object *o, Type newType, uint requested, bool enforceAtt
} }
storeValue(lastFree, UINT_MAX); storeValue(lastFree, UINT_MAX);
} }
Q_ASSERT(Value::fromReturnedValue(sparse->freeList).isEmpty());
// ### Could explicitly free the old data // ### Could explicitly free the old data
} }
@ -361,12 +364,12 @@ void SparseArrayData::free(Heap::ArrayData *d, uint idx)
Value *v = d->arrayData + idx; Value *v = d->arrayData + idx;
if (d->attrs && d->attrs[idx].isAccessor()) { if (d->attrs && d->attrs[idx].isAccessor()) {
// double slot, free both. Order is important, so we have a double slot for allocation again afterwards. // double slot, free both. Order is important, so we have a double slot for allocation again afterwards.
v[1].setTagValue(Value::Empty_Type, Value::fromReturnedValue(d->freeList).value()); v[1].setEmpty(Value::fromReturnedValue(d->freeList).emptyValue());
v[0].setTagValue(Value::Empty_Type, idx + 1); v[0].setEmpty(idx + 1);
} else { } else {
v->setTagValue(Value::Empty_Type, Value::fromReturnedValue(d->freeList).value()); v->setEmpty(Value::fromReturnedValue(d->freeList).emptyValue());
} }
d->freeList = idx; d->freeList = Primitive::emptyValue(idx).asReturnedValue();
if (d->attrs) if (d->attrs)
d->attrs[idx].clear(); d->attrs[idx].clear();
} }
@ -404,9 +407,9 @@ uint SparseArrayData::allocate(Object *o, bool doubleSlot)
Q_ASSERT(dd->arrayData[Value::fromReturnedValue(*last).value()].value() != Value::fromReturnedValue(*last).value()); Q_ASSERT(dd->arrayData[Value::fromReturnedValue(*last).value()].value() != Value::fromReturnedValue(*last).value());
if (dd->arrayData[Value::fromReturnedValue(*last).value()].value() == (Value::fromReturnedValue(*last).value() + 1)) { if (dd->arrayData[Value::fromReturnedValue(*last).value()].value() == (Value::fromReturnedValue(*last).value() + 1)) {
// found two slots in a row // found two slots in a row
uint idx = Value::fromReturnedValue(*last).uint_32(); uint idx = Value::fromReturnedValue(*last).emptyValue();
Value lastV = Value::fromReturnedValue(*last); Value lastV = Value::fromReturnedValue(*last);
lastV.setTagValue(lastV.tag(), dd->arrayData[lastV.value() + 1].value()); lastV.setEmpty(dd->arrayData[lastV.emptyValue() + 1].value());
*last = lastV.rawValue(); *last = lastV.rawValue();
dd->attrs[idx] = Attr_Accessor; dd->attrs[idx] = Attr_Accessor;
return idx; return idx;
@ -420,7 +423,8 @@ uint SparseArrayData::allocate(Object *o, bool doubleSlot)
} }
uint idx = Value::fromReturnedValue(dd->freeList).value(); uint idx = Value::fromReturnedValue(dd->freeList).value();
Q_ASSERT(idx != UINT_MAX); Q_ASSERT(idx != UINT_MAX);
dd->freeList = dd->arrayData[idx].uint_32(); dd->freeList = dd->arrayData[idx].asReturnedValue();
Q_ASSERT(Value::fromReturnedValue(dd->freeList).isEmpty());
if (dd->attrs) if (dd->attrs)
dd->attrs[idx] = Attr_Data; dd->attrs[idx] = Attr_Data;
return idx; return idx;
@ -475,13 +479,14 @@ bool SparseArrayData::del(Object *o, uint index)
if (isAccessor) { if (isAccessor) {
// free up both indices // free up both indices
dd->arrayData[pidx + 1].setTagValue(Value::Empty_Type, Value::fromReturnedValue(dd->freeList).value()); dd->arrayData[pidx + 1].setEmpty(Value::fromReturnedValue(dd->freeList).emptyValue());
dd->arrayData[pidx].setTagValue(Value::Undefined_Type, pidx + 1); dd->arrayData[pidx].setEmpty(pidx + 1);
} else { } else {
dd->arrayData[pidx].setTagValue(Value::Empty_Type, Value::fromReturnedValue(dd->freeList).value()); Q_ASSERT(dd->type == Heap::ArrayData::Sparse);
dd->arrayData[pidx].setEmpty(Value::fromReturnedValue(dd->freeList).emptyValue());
} }
dd->freeList = pidx; dd->freeList = Primitive::emptyValue(pidx).asReturnedValue();
dd->sparse->erase(n); dd->sparse->erase(n);
return true; return true;
} }

View File

@ -139,7 +139,7 @@ PersistentValueStorage::Iterator &PersistentValueStorage::Iterator::operator++()
while (p) { while (p) {
while (index < kEntriesPerPage - 1) { while (index < kEntriesPerPage - 1) {
++index; ++index;
if (static_cast<Page *>(p)->values[index].tag() != QV4::Value::Empty_Type) if (!static_cast<Page *>(p)->values[index].isEmpty())
return *this; return *this;
} }
index = -1; index = -1;

View File

@ -175,10 +175,7 @@ public:
Q_ALWAYS_INLINE quint32 value() const { return _val & quint64(~quint32(0)); } Q_ALWAYS_INLINE quint32 value() const { return _val & quint64(~quint32(0)); }
Q_ALWAYS_INLINE quint32 tag() const { return _val >> 32; } Q_ALWAYS_INLINE quint32 tag() const { return _val >> 32; }
#if defined(V4_BOOTSTRAP) #if defined(QV4_USE_64_BIT_VALUE_ENCODING)
Q_ALWAYS_INLINE Heap::Base *m() const { Q_UNREACHABLE(); return Q_NULLPTR; }
Q_ALWAYS_INLINE void setM(Heap::Base *b) { Q_UNUSED(b); Q_UNREACHABLE(); }
#elif defined(QV4_USE_64_BIT_VALUE_ENCODING)
Q_ALWAYS_INLINE Heap::Base *m() const Q_ALWAYS_INLINE Heap::Base *m() const
{ {
Heap::Base *b; Heap::Base *b;
@ -226,6 +223,17 @@ public:
setTagValue(Empty_Type_Internal, quint32(i)); setTagValue(Empty_Type_Internal, quint32(i));
} }
Q_ALWAYS_INLINE void setEmpty(quint32 i)
{
setTagValue(Empty_Type_Internal, i);
}
Q_ALWAYS_INLINE quint32 emptyValue()
{
Q_ASSERT(isEmpty());
return quint32(value());
}
enum Type { enum Type {
Undefined_Type, Undefined_Type,
Managed_Type, Managed_Type,
@ -530,6 +538,7 @@ ReturnedValue Heap::Base::asReturnedValue() const
struct Q_QML_PRIVATE_EXPORT Primitive : public Value struct Q_QML_PRIVATE_EXPORT Primitive : public Value
{ {
inline static Primitive emptyValue(); inline static Primitive emptyValue();
inline static Primitive emptyValue(uint v);
static inline Primitive fromBoolean(bool b); static inline Primitive fromBoolean(bool b);
static inline Primitive fromInt32(int i); static inline Primitive fromInt32(int i);
inline static Primitive undefinedValue(); inline static Primitive undefinedValue();
@ -559,6 +568,13 @@ inline Primitive Primitive::emptyValue()
return v; return v;
} }
inline Primitive Primitive::emptyValue(uint e)
{
Primitive v;
v.setEmpty(e);
return v;
}
inline Primitive Primitive::nullValue() inline Primitive Primitive::nullValue()
{ {
Primitive v; Primitive v;

View File

@ -460,7 +460,7 @@ void MemoryManager::sweep(bool lastSweep)
remainingWeakQObjectWrappers.reserve(pendingCount); remainingWeakQObjectWrappers.reserve(pendingCount);
for (int i = 0; i < pendingCount; ++i) { for (int i = 0; i < pendingCount; ++i) {
Value *v = m_pendingFreedObjectWrapperValue.at(i); Value *v = m_pendingFreedObjectWrapperValue.at(i);
if (v->tag() == Value::Undefined_Type) if (v->isUndefined() || v->isEmpty())
PersistentValueStorage::free(v); PersistentValueStorage::free(v);
else else
remainingWeakQObjectWrappers.append(v); remainingWeakQObjectWrappers.append(v);

View File

@ -67,10 +67,6 @@ int QAccessibleQuickItem::childCount() const
QRect QAccessibleQuickItem::rect() const QRect QAccessibleQuickItem::rect() const
{ {
const QRect r = itemScreenRect(item()); const QRect r = itemScreenRect(item());
if (!r.isValid()) {
qWarning() << item()->metaObject()->className() << item()->property("accessibleText") << r;
}
return r; return r;
} }

View File

@ -708,7 +708,7 @@ void QQuickDragAttached::cancel()
*/ */
/*! /*!
\qmlattachedsignal QtQuick::Drag::dragFinished(DropAction action) \qmlattachedsignal QtQuick::Drag::dragFinished(DropAction dropAction)
This signal is emitted when a drag finishes and the drag was started with the This signal is emitted when a drag finishes and the drag was started with the
\l startDrag() method or started automatically using the \l dragType property. \l startDrag() method or started automatically using the \l dragType property.

View File

@ -2264,8 +2264,8 @@ QString QQuickTextInput::preeditText() const
If true, the user can use the mouse to select text in some If true, the user can use the mouse to select text in some
platform-specific way. Note that for some platforms this may platform-specific way. Note that for some platforms this may
not be an appropriate interaction (eg. may conflict with how not be an appropriate interaction (it may conflict with how
the text needs to behave inside a Flickable. the text needs to behave inside a \l Flickable, for example).
*/ */
bool QQuickTextInput::selectByMouse() const bool QQuickTextInput::selectByMouse() const
{ {

View File

@ -1884,6 +1884,7 @@ bool QQuickWindowPrivate::deliverWheelEvent(QQuickItem *item, QWheelEvent *event
if (item->contains(p)) { if (item->contains(p)) {
QWheelEvent wheel(p, p, event->pixelDelta(), event->angleDelta(), event->delta(), QWheelEvent wheel(p, p, event->pixelDelta(), event->angleDelta(), event->delta(),
event->orientation(), event->buttons(), event->modifiers(), event->phase(), event->source(), event->inverted()); event->orientation(), event->buttons(), event->modifiers(), event->phase(), event->source(), event->inverted());
wheel.setTimestamp(event->timestamp());
wheel.accept(); wheel.accept();
q->sendEvent(item, &wheel); q->sendEvent(item, &wheel);
if (wheel.isAccepted()) { if (wheel.isAccepted()) {

View File

@ -239,7 +239,8 @@ bool QSG24BitTextMaskShader::useSRGB() const
// m_useSRGB is true, but if some QOGLFBO was bound check it's texture format: // m_useSRGB is true, but if some QOGLFBO was bound check it's texture format:
QOpenGLContext *ctx = QOpenGLContext::currentContext(); QOpenGLContext *ctx = QOpenGLContext::currentContext();
QOpenGLFramebufferObject *qfbo = QOpenGLContextPrivate::get(ctx)->qgl_current_fbo; QOpenGLFramebufferObject *qfbo = QOpenGLContextPrivate::get(ctx)->qgl_current_fbo;
return !qfbo || qfbo->format().internalTextureFormat() == GL_SRGB8_ALPHA8_EXT; bool fboInvalid = QOpenGLContextPrivate::get(ctx)->qgl_current_fbo_invalid;
return !qfbo || fboInvalid || qfbo->format().internalTextureFormat() == GL_SRGB8_ALPHA8_EXT;
#else #else
return m_useSRGB; return m_useSRGB;
#endif #endif

View File

@ -48,7 +48,7 @@ public:
TestItem(QQuickItem *parent = 0) TestItem(QQuickItem *parent = 0)
: QQuickItem(parent), focused(false), pressCount(0), releaseCount(0) : QQuickItem(parent), focused(false), pressCount(0), releaseCount(0)
, wheelCount(0), acceptIncomingTouchEvents(true) , wheelCount(0), acceptIncomingTouchEvents(true)
, touchEventReached(false) {} , touchEventReached(false), timestamp(0) {}
bool focused; bool focused;
int pressCount; int pressCount;
@ -56,6 +56,7 @@ public:
int wheelCount; int wheelCount;
bool acceptIncomingTouchEvents; bool acceptIncomingTouchEvents;
bool touchEventReached; bool touchEventReached;
ulong timestamp;
protected: protected:
virtual void focusInEvent(QFocusEvent *) { Q_ASSERT(!focused); focused = true; } virtual void focusInEvent(QFocusEvent *) { Q_ASSERT(!focused); focused = true; }
virtual void focusOutEvent(QFocusEvent *) { Q_ASSERT(focused); focused = false; } virtual void focusOutEvent(QFocusEvent *) { Q_ASSERT(focused); focused = false; }
@ -65,7 +66,7 @@ protected:
touchEventReached = true; touchEventReached = true;
event->setAccepted(acceptIncomingTouchEvents); event->setAccepted(acceptIncomingTouchEvents);
} }
virtual void wheelEvent(QWheelEvent *event) { event->accept(); ++wheelCount; } virtual void wheelEvent(QWheelEvent *event) { event->accept(); ++wheelCount; timestamp = event->timestamp(); }
}; };
class TestWindow: public QQuickWindow class TestWindow: public QQuickWindow
@ -1432,12 +1433,14 @@ void tst_qquickitem::wheelEvent()
item->setVisible(visible); item->setVisible(visible);
QWheelEvent event(QPoint(100, 50), -120, Qt::NoButton, Qt::NoModifier, Qt::Vertical); QWheelEvent event(QPoint(100, 50), -120, Qt::NoButton, Qt::NoModifier, Qt::Vertical);
event.setTimestamp(123456UL);
event.setAccepted(false); event.setAccepted(false);
QGuiApplication::sendEvent(&window, &event); QGuiApplication::sendEvent(&window, &event);
if (shouldReceiveWheelEvents) { if (shouldReceiveWheelEvents) {
QVERIFY(event.isAccepted()); QVERIFY(event.isAccepted());
QCOMPARE(item->wheelCount, 1); QCOMPARE(item->wheelCount, 1);
QCOMPARE(item->timestamp, 123456UL);
} else { } else {
QVERIFY(!event.isAccepted()); QVERIFY(!event.isAccepted());
QCOMPARE(item->wheelCount, 0); QCOMPARE(item->wheelCount, 0);

View File

@ -1,6 +1,4 @@
[dependentImplicitSizes] [dependentImplicitSizes]
* *
[mouseSelection]
*
[lineLaidOutRelayout] [lineLaidOutRelayout]
msvc-2015 msvc-2015

View File

@ -1,5 +1,3 @@
[mouseSelection]
*
[undo] [undo]
* *
[undo_keypressevents] [undo_keypressevents]

View File

@ -2003,12 +2003,18 @@ void tst_qquicktextedit::mouseSelection()
else if (clicks == 3) else if (clicks == 3)
QTest::mouseDClick(&window, Qt::LeftButton, Qt::NoModifier, p1); QTest::mouseDClick(&window, Qt::LeftButton, Qt::NoModifier, p1);
QTest::mousePress(&window, Qt::LeftButton, Qt::NoModifier, p1); QTest::mousePress(&window, Qt::LeftButton, Qt::NoModifier, p1);
if (clicks == 2) {
// QTBUG-50022: Since qtbase commit beef975, QTestLib avoids generating
// double click events by adding 500ms delta to release event timestamps.
// Send a double click event by hand to ensure the correct sequence:
// press, release, press, _dbl click_, move, release.
QMouseEvent dblClickEvent(QEvent::MouseButtonDblClick, p1, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
QGuiApplication::sendEvent(textEditObject, &dblClickEvent);
}
QTest::mouseMove(&window, p2); QTest::mouseMove(&window, p2);
QTest::mouseRelease(&window, Qt::LeftButton, Qt::NoModifier, p2); QTest::mouseRelease(&window, Qt::LeftButton, Qt::NoModifier, p2);
QTRY_COMPARE(textEditObject->selectedText(), selectedText); QTRY_COMPARE(textEditObject->selectedText(), selectedText);
QTest::qWait(QGuiApplication::styleHints()->mouseDoubleClickInterval() + 10);
// Clicking and shift to clicking between the same points should select the same text. // Clicking and shift to clicking between the same points should select the same text.
textEditObject->setCursorPosition(0); textEditObject->setCursorPosition(0);
if (clicks > 1) if (clicks > 1)
@ -2017,9 +2023,6 @@ void tst_qquicktextedit::mouseSelection()
QTest::mouseClick(&window, Qt::LeftButton, Qt::NoModifier, p1); QTest::mouseClick(&window, Qt::LeftButton, Qt::NoModifier, p1);
QTest::mouseClick(&window, Qt::LeftButton, Qt::ShiftModifier, p2); QTest::mouseClick(&window, Qt::LeftButton, Qt::ShiftModifier, p2);
QTRY_COMPARE(textEditObject->selectedText(), selectedText); QTRY_COMPARE(textEditObject->selectedText(), selectedText);
// ### This is to prevent double click detection from carrying over to the next test.
QTest::qWait(QGuiApplication::styleHints()->mouseDoubleClickInterval() + 10);
} }
void tst_qquicktextedit::dragMouseSelection() void tst_qquicktextedit::dragMouseSelection()
@ -2960,9 +2963,6 @@ void tst_qquicktextedit::middleClickPaste()
// Middle click pastes the selected text, assuming the platform supports it. // Middle click pastes the selected text, assuming the platform supports it.
QTest::mouseClick(&window, Qt::MiddleButton, Qt::NoModifier, p3); QTest::mouseClick(&window, Qt::MiddleButton, Qt::NoModifier, p3);
// ### This is to prevent double click detection from carrying over to the next test.
QTest::qWait(QGuiApplication::styleHints()->mouseDoubleClickInterval() + 10);
if (QGuiApplication::clipboard()->supportsSelection()) if (QGuiApplication::clipboard()->supportsSelection())
QCOMPARE(textEditObject->text().mid(1, selectedText.length()), selectedText); QCOMPARE(textEditObject->text().mid(1, selectedText.length()), selectedText);
else else

View File

@ -0,0 +1,18 @@
// test use of Fixedsys font on Windows
import QtQuick 2.0
Item {
width: 320
height: 480
Text {
anchors.fill: parent
wrapMode: Text.Wrap
font.family: "Fixedsys"
font.pixelSize: 20
text: "Foobar"
}
}