aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--src/qml/compiler/qqmlirbuilder.cpp36
-rw-r--r--src/qml/compiler/qv4compileddata_p.h4
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp6
-rw-r--r--src/qml/qml.pro3
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp20
-rw-r--r--src/qml/qtqml.tracepoints14
-rw-r--r--src/quick/accessible/qaccessiblequickitem.cpp16
-rw-r--r--src/quick/accessible/qaccessiblequickitem_p.h1
-rw-r--r--src/quick/items/context2d/qquickcontext2d.cpp12
-rw-r--r--src/quick/items/qquickaccessibleattached_p.h8
-rw-r--r--src/quick/items/qquicktextcontrol.cpp3
-rw-r--r--tests/auto/quick/qquickaccessible/data/text.qml (renamed from tests/auto/quick/qquickaccessible/data/statictext.qml)18
-rw-r--r--tests/auto/quick/qquickaccessible/tst_qquickaccessible.cpp46
14 files changed, 150 insertions, 38 deletions
diff --git a/.gitignore b/.gitignore
index 57606bfacf..9905dd1fdc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -32,6 +32,7 @@ wrapper.bat
*.*#
core
.qmake.cache
+.qmake.stash
.qmake.vars
*.prl
tags
diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp
index cd3953044b..41bdc3ae92 100644
--- a/src/qml/compiler/qqmlirbuilder.cpp
+++ b/src/qml/compiler/qqmlirbuilder.cpp
@@ -1550,15 +1550,12 @@ void QmlUnitGenerator::generate(Document &output, const QV4::CompiledData::Depen
QQmlRefPointer<QV4::CompiledData::CompilationUnit> compilationUnit = output.javaScriptCompilationUnit;
- const QV4::CompiledData::Unit *jsUnit = nullptr;
- std::function<QV4::CompiledData::QmlUnit *(QV4::CompiledData::QmlUnit *, uint)> unitFinalizer
- = [](QV4::CompiledData::QmlUnit *unit, uint) {
- return unit;
- };
+ QV4::CompiledData::Unit *jsUnit = nullptr;
+ const bool finalize = !compilationUnit->data;
// We may already have unit data if we're loading an ahead-of-time generated cache file.
- if (compilationUnit->data) {
- jsUnit = compilationUnit->data;
+ if (!finalize) {
+ jsUnit = const_cast<QV4::CompiledData::Unit *>(compilationUnit->data);
output.javaScriptCompilationUnit->dynamicStrings = output.jsGenerator.stringTable.allStrings();
} else {
QV4::CompiledData::Unit *createdUnit;
@@ -1585,20 +1582,6 @@ void QmlUnitGenerator::generate(Document &output, const QV4::CompiledData::Depen
createdUnit->sourceFileIndex = output.jsGenerator.stringTable.getStringId(output.jsModule.fileName);
createdUnit->finalUrlIndex = output.jsGenerator.stringTable.getStringId(output.jsModule.finalUrl);
-
- // Combine the qml data into the general unit data.
- unitFinalizer = [&jsUnit](QV4::CompiledData::QmlUnit *qmlUnit, uint qmlDataSize) {
- void *ptr = const_cast<QV4::CompiledData::Unit*>(jsUnit);
- QV4::CompiledData::Unit *newUnit = (QV4::CompiledData::Unit *)realloc(ptr, jsUnit->unitSize + qmlDataSize);
- jsUnit = newUnit;
- newUnit->offsetToQmlUnit = newUnit->unitSize;
- newUnit->unitSize += qmlDataSize;
- memcpy(const_cast<QV4::CompiledData::QmlUnit *>(newUnit->qmlUnit()), qmlUnit, qmlDataSize);
- free(const_cast<QV4::CompiledData::QmlUnit*>(qmlUnit));
- qmlUnit = nullptr;
- newUnit->generateChecksum();
- return const_cast<QV4::CompiledData::QmlUnit*>(newUnit->qmlUnit());
- };
}
// No more new strings after this point, we're calculating offsets.
@@ -1765,7 +1748,16 @@ void QmlUnitGenerator::generate(Document &output, const QV4::CompiledData::Depen
}
}
- qmlUnit = unitFinalizer(qmlUnit, totalSize);
+ if (finalize) {
+ // Combine the qml data into the general unit data.
+ jsUnit = static_cast<QV4::CompiledData::Unit *>(realloc(jsUnit, jsUnit->unitSize + totalSize));
+ jsUnit->offsetToQmlUnit = jsUnit->unitSize;
+ jsUnit->unitSize += totalSize;
+ memcpy(jsUnit->qmlUnit(), qmlUnit, totalSize);
+ free(qmlUnit);
+ jsUnit->generateChecksum();
+ qmlUnit = jsUnit->qmlUnit();
+ }
static const bool showStats = qEnvironmentVariableIsSet("QML_SHOW_UNIT_STATS");
if (showStats) {
diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h
index 3e89c25c7d..4a90c841bb 100644
--- a/src/qml/compiler/qv4compileddata_p.h
+++ b/src/qml/compiler/qv4compileddata_p.h
@@ -904,6 +904,10 @@ struct Unit
return reinterpret_cast<const QmlUnit *>(reinterpret_cast<const char *>(this) + offsetToQmlUnit);
}
+ QmlUnit *qmlUnit() {
+ return reinterpret_cast<QmlUnit *>(reinterpret_cast<char *>(this) + offsetToQmlUnit);
+ }
+
bool isSingleton() const {
return flags & Unit::IsSingleton;
}
diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp
index ec44f42933..d348a79861 100644
--- a/src/qml/jsruntime/qv4vme_moth.cpp
+++ b/src/qml/jsruntime/qv4vme_moth.cpp
@@ -65,6 +65,8 @@
#include <private/qv4baselinejit_p.h>
#endif
+#include <qtqml_tracepoints_p.h>
+
#undef COUNT_INSTRUCTIONS
enum { ShowWhenDeoptimiationHappens = 0 };
@@ -422,6 +424,10 @@ ReturnedValue VME::exec(CppStackFrame *frame, ExecutionEngine *engine)
CHECK_STACK_LIMITS(engine);
Function *function = frame->v4Function;
+ Q_TRACE_SCOPE(QQmlV4_function_call, engine, function->name()->toQString(),
+ function->compilationUnit->fileName(),
+ function->compiledFunction->location.line,
+ function->compiledFunction->location.column);
Profiling::FunctionCallProfiler profiler(engine, function); // start execution profiling
QV4::Debugging::Debugger *debugger = engine->debugger();
diff --git a/src/qml/qml.pro b/src/qml/qml.pro
index ca3282556e..5cb51e0d03 100644
--- a/src/qml/qml.pro
+++ b/src/qml/qml.pro
@@ -4,6 +4,9 @@ QT = core-private
qtConfig(qml-network): \
QT += network
+TRACEPOINT_PROVIDER = $$PWD/qtqml.tracepoints
+CONFIG += qt_tracepoints
+
DEFINES += QT_NO_URL_CAST_FROM_STRING QT_NO_INTEGER_EVENT_COORDINATES
msvc:equals(QT_ARCH, i386): QMAKE_LFLAGS += /BASE:0x66000000
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
index 26d3b5b6c1..18105aa75f 100644
--- a/src/qml/qml/qqmlobjectcreator.cpp
+++ b/src/qml/qml/qqmlobjectcreator.cpp
@@ -57,6 +57,8 @@
#include <private/qqmldebugserviceinterfaces_p.h>
#include <private/qjsvalue_p.h>
+#include <qtqml_tracepoints_p.h>
+
QT_USE_NAMESPACE
namespace {
@@ -1161,6 +1163,9 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo
{
const QV4::CompiledData::Object *obj = compilationUnit->objectAt(index);
QQmlObjectCreationProfiler profiler(sharedState->profiler.profiler, obj);
+ Q_TRACE(QQmlObjectCreator_createInstance_entry, compilationUnit.data(), obj, context->url());
+ QString typeName;
+ Q_TRACE_EXIT(QQmlObjectCreator_createInstance_exit, typeName);
ActiveOCRestorer ocRestorer(this, QQmlEnginePrivate::get(engine));
@@ -1174,8 +1179,7 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo
if (obj->flags & QV4::CompiledData::Object::IsComponent) {
isComponent = true;
QQmlComponent *component = new QQmlComponent(engine, compilationUnit.data(), index, parent);
- Q_QML_OC_PROFILE(sharedState->profiler, profiler.update(
- compilationUnit.data(), obj, QStringLiteral("<component>"), context->url()));
+ typeName = QStringLiteral("<component>");
QQmlComponentPrivate::get(component)->creationContext = context;
instance = component;
ddata = QQmlData::get(instance, /*create*/true);
@@ -1186,8 +1190,7 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo
installPropertyCache = !typeRef->isFullyDynamicType;
QQmlType type = typeRef->type;
if (type.isValid()) {
- Q_QML_OC_PROFILE(sharedState->profiler, profiler.update(
- compilationUnit.data(), obj, type.qmlTypeName(), context->url()));
+ typeName = type.qmlTypeName();
void *ddataMemory = nullptr;
type.create(&instance, &ddataMemory, sizeof(QQmlData));
@@ -1219,9 +1222,7 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo
sharedState->allCreatedObjects.push(instance);
} else {
Q_ASSERT(typeRef->compilationUnit);
- Q_QML_OC_PROFILE(sharedState->profiler, profiler.update(
- compilationUnit.data(), obj, typeRef->compilationUnit->fileName(),
- context->url()));
+ typeName = typeRef->compilationUnit->fileName();
if (typeRef->compilationUnit->unitData()->isSingleton())
{
recordError(obj->location, tr("Composite Singleton Type %1 is not creatable").arg(stringAt(obj->inheritedTypeNameIndex)));
@@ -1248,6 +1249,11 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo
ddata = QQmlData::get(instance, /*create*/true);
}
+
+ Q_QML_OC_PROFILE(sharedState->profiler, profiler.update(
+ compilationUnit.data(), obj, typeName, context->url()));
+ Q_UNUSED(typeName); // only relevant for tracing
+
ddata->lineNumber = obj->location.line;
ddata->columnNumber = obj->location.column;
diff --git a/src/qml/qtqml.tracepoints b/src/qml/qtqml.tracepoints
new file mode 100644
index 0000000000..841748f201
--- /dev/null
+++ b/src/qml/qtqml.tracepoints
@@ -0,0 +1,14 @@
+{
+namespace QV4 {
+class ExecutionEngine;
+namespace CompiledData {
+class CompilationUnit;
+class Object;
+} // CompiledData
+} // QV4
+}
+
+QQmlObjectCreator_createInstance_entry(const QV4::CompiledData::CompilationUnit *compilationUnit, const QV4::CompiledData::Object *object, const QUrl &url)
+QQmlObjectCreator_createInstance_exit(const QString &typeName)
+QQmlV4_function_call_entry(const QV4::ExecutionEngine *engine, const QString &function, const QString &fileName, int line, int column)
+QQmlV4_function_call_exit()
diff --git a/src/quick/accessible/qaccessiblequickitem.cpp b/src/quick/accessible/qaccessiblequickitem.cpp
index 98e7663c96..b87203c3ef 100644
--- a/src/quick/accessible/qaccessiblequickitem.cpp
+++ b/src/quick/accessible/qaccessiblequickitem.cpp
@@ -382,6 +382,22 @@ QString QAccessibleQuickItem::text(QAccessible::Text textType) const
return QString();
}
+void QAccessibleQuickItem::setText(QAccessible::Text textType, const QString &text)
+{
+ if (role() != QAccessible::EditableText)
+ return;
+ if (textType != QAccessible::Value)
+ return;
+
+ if (QTextDocument *doc = textDocument()) {
+ doc->setPlainText(text);
+ return;
+ }
+ auto textPropertyName = "text";
+ if (object()->metaObject()->indexOfProperty(textPropertyName) >= 0)
+ object()->setProperty(textPropertyName, text);
+}
+
void *QAccessibleQuickItem::interface_cast(QAccessible::InterfaceType t)
{
QAccessible::Role r = role();
diff --git a/src/quick/accessible/qaccessiblequickitem_p.h b/src/quick/accessible/qaccessiblequickitem_p.h
index 5375d37bf0..931e995f0f 100644
--- a/src/quick/accessible/qaccessiblequickitem_p.h
+++ b/src/quick/accessible/qaccessiblequickitem_p.h
@@ -83,6 +83,7 @@ public:
QAccessible::State state() const override;
QAccessible::Role role() const override;
QString text(QAccessible::Text) const override;
+ void setText(QAccessible::Text, const QString &text) override;
bool isAccessible() const;
diff --git a/src/quick/items/context2d/qquickcontext2d.cpp b/src/quick/items/context2d/qquickcontext2d.cpp
index 5640721c6f..0f104a122f 100644
--- a/src/quick/items/context2d/qquickcontext2d.cpp
+++ b/src/quick/items/context2d/qquickcontext2d.cpp
@@ -2000,7 +2000,7 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_miterLimit(const QV4::FunctionO
\since QtQuick 2.11
Returns an array of qreals representing the dash pattern of the line.
- \sa setLineDash()
+ \sa setLineDash(), lineDashOffset
*/
QV4::ReturnedValue QQuickJSContext2DPrototype::method_getLineDash(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
@@ -2022,7 +2022,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_getLineDash(const QV4::Fun
/*!
\qmlmethod QtQuick::Context2D::setLineDash(array pattern)
\since QtQuick 2.11
- Sets the dash pattern to the given pattern
+ Sets the dash pattern to the given pattern.
\a pattern a list of numbers that specifies distances to alternately draw a line and a gap.
@@ -2041,7 +2041,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_getLineDash(const QV4::Fun
\endcode
\endtable
- \sa setLineDash
+ \sa getLineDash(), lineDashOffset
*/
QV4::ReturnedValue QQuickJSContext2DPrototype::method_setLineDash(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
@@ -2083,8 +2083,10 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_setLineDash(const QV4::Fun
\qmlproperty real QtQuick::Context2D::lineDashOffset
\since QtQuick 2.11
- Holds the current line dash offset
- The default line dash ofset value is 0
+ Holds the current line dash offset.
+ The default line dash offset value is \c 0.
+
+ \sa getLineDash(), setLineDash()
*/
QV4::ReturnedValue QQuickJSContext2D::method_get_lineDashOffset(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
diff --git a/src/quick/items/qquickaccessibleattached_p.h b/src/quick/items/qquickaccessibleattached_p.h
index 215a1e5db6..e292c280df 100644
--- a/src/quick/items/qquickaccessibleattached_p.h
+++ b/src/quick/items/qquickaccessibleattached_p.h
@@ -128,13 +128,19 @@ public:
case QAccessible::Button:
case QAccessible::MenuItem:
case QAccessible::PageTab:
- case QAccessible::EditableText:
case QAccessible::SpinBox:
case QAccessible::ComboBox:
case QAccessible::Terminal:
case QAccessible::ScrollBar:
m_state.focusable = true;
break;
+ case QAccessible::EditableText:
+ m_state.editable = true;
+ m_state.focusable = true;
+ break;
+ case QAccessible::StaticText:
+ m_state.readOnly = true;
+ break;
default:
break;
}
diff --git a/src/quick/items/qquicktextcontrol.cpp b/src/quick/items/qquicktextcontrol.cpp
index a7a90c9134..caef24293a 100644
--- a/src/quick/items/qquicktextcontrol.cpp
+++ b/src/quick/items/qquicktextcontrol.cpp
@@ -1297,6 +1297,7 @@ void QQuickTextControlPrivate::inputMethodEvent(QInputMethodEvent *e)
|| e->preeditString() != cursor.block().layout()->preeditAreaText()
|| e->replacementLength() > 0;
bool forceSelectionChanged = false;
+ int oldCursorPos = cursor.position();
cursor.beginEditBlock();
if (isGettingInput) {
@@ -1365,6 +1366,8 @@ void QQuickTextControlPrivate::inputMethodEvent(QInputMethodEvent *e)
QTextCursorPrivate *cursor_d = QTextCursorPrivate::getPrivate(&cursor);
if (cursor_d)
cursor_d->setX();
+ if (cursor.position() != oldCursorPos)
+ emit q->cursorPositionChanged();
q->updateCursorRectangle(oldPreeditCursor != preeditCursor || forceSelectionChanged || isGettingInput);
selectionChanged(forceSelectionChanged);
}
diff --git a/tests/auto/quick/qquickaccessible/data/statictext.qml b/tests/auto/quick/qquickaccessible/data/text.qml
index 1092f33daf..88f292a61f 100644
--- a/tests/auto/quick/qquickaccessible/data/statictext.qml
+++ b/tests/auto/quick/qquickaccessible/data/text.qml
@@ -28,4 +28,22 @@ Item {
Accessible.name: "The Hello 2 accessible text"
Accessible.description: "A text description"
}
+
+ TextInput {
+ x: 100
+ y: 80
+ width: 200
+ height: 40
+ text: "A text input"
+ Accessible.role: Accessible.EditableText
+ }
+
+ TextEdit {
+ x: 100
+ y: 120
+ width: 200
+ height: 100
+ text: "A multi-line text edit\nTesting Accessibility."
+ Accessible.role: Accessible.EditableText
+ }
}
diff --git a/tests/auto/quick/qquickaccessible/tst_qquickaccessible.cpp b/tests/auto/quick/qquickaccessible/tst_qquickaccessible.cpp
index 1bfeb94161..243d87f212 100644
--- a/tests/auto/quick/qquickaccessible/tst_qquickaccessible.cpp
+++ b/tests/auto/quick/qquickaccessible/tst_qquickaccessible.cpp
@@ -130,7 +130,7 @@ void tst_QQuickAccessible::commonTests_data()
{
QTest::addColumn<QString>("accessibleRoleFileName");
- QTest::newRow("StaticText") << "statictext.qml";
+ QTest::newRow("Text") << "text.qml";
QTest::newRow("PushButton") << "pushbutton.qml";
}
@@ -302,7 +302,7 @@ void tst_QQuickAccessible::basicPropertiesTest()
QCOMPARE(app->childCount(), 0);
QQuickView *window = new QQuickView();
- window->setSource(testFileUrl("statictext.qml"));
+ window->setSource(testFileUrl("text.qml"));
window->show();
QCOMPARE(app->childCount(), 1);
@@ -312,7 +312,7 @@ void tst_QQuickAccessible::basicPropertiesTest()
QAccessibleInterface *item = iface->child(0);
QVERIFY(item);
- QCOMPARE(item->childCount(), 2);
+ QCOMPARE(item->childCount(), 4);
QCOMPARE(item->rect().size(), QSize(400, 400));
QCOMPARE(item->role(), QAccessible::Client);
QCOMPARE(iface->indexOfChild(item), 0);
@@ -338,10 +338,50 @@ void tst_QQuickAccessible::basicPropertiesTest()
QCOMPARE(text2->rect().y(), item->rect().y() + 40);
QCOMPARE(text2->role(), QAccessible::StaticText);
QCOMPARE(item->indexOfChild(text2), 1);
+ QCOMPARE(text2->state().editable, 0);
+ QCOMPARE(text2->state().readOnly, 1);
QCOMPARE(iface->indexOfChild(text2), -1);
QCOMPARE(text2->indexOfChild(item), -1);
+ // TextInput
+ QAccessibleInterface *textInput = item->child(2);
+ QVERIFY(textInput);
+ QCOMPARE(textInput->childCount(), 0);
+ QCOMPARE(textInput->role(), QAccessible::EditableText);
+ QCOMPARE(textInput->state().editable, 1);
+ QCOMPARE(textInput->state().readOnly, 0);
+ QCOMPARE(textInput->state().multiLine, 0);
+ QCOMPARE(textInput->state().focusable, 1);
+ QCOMPARE(textInput->text(QAccessible::Value), "A text input");
+ auto textInterface = textInput->textInterface();
+ QVERIFY(textInterface);
+ auto editableTextInterface = textInput->editableTextInterface();
+ QEXPECT_FAIL("", "EditableTextInterface is not implemented", Continue);
+ QVERIFY(editableTextInterface);
+ auto newText = QString("a new text");
+ textInput->setText(QAccessible::Value, newText);
+ QCOMPARE(textInput->text(QAccessible::Value), newText);
+
+ // TextEdit
+ QAccessibleInterface *textEdit = item->child(3);
+ QVERIFY(textEdit);
+ QCOMPARE(textEdit->childCount(), 0);
+ QCOMPARE(textEdit->role(), QAccessible::EditableText);
+ QCOMPARE(textEdit->state().editable, 1);
+ QCOMPARE(textEdit->state().readOnly, 0);
+ QCOMPARE(textEdit->state().focusable, 1);
+ QCOMPARE(textEdit->text(QAccessible::Value), "A multi-line text edit\nTesting Accessibility.");
+ auto textEditTextInterface = textEdit->textInterface();
+ QVERIFY(textEditTextInterface);
+ auto textEditEditableTextInterface = textEdit->editableTextInterface();
+ QEXPECT_FAIL("", "EditableTextInterface is not implemented", Continue);
+ QVERIFY(textEditEditableTextInterface);
+ textEdit->setText(QAccessible::Value, newText);
+ QCOMPARE(textEdit->text(QAccessible::Value), newText);
+ QEXPECT_FAIL("", "multi line is not implemented", Continue);
+ QCOMPARE(textInput->state().multiLine, 1);
+
delete window;
QTestAccessibility::clearEvents();
}