Merge remote-tracking branch 'origin/5.9' into dev
Conflicts: src/qml/jit/qv4assembler.cpp src/qml/jit/qv4assembler_p.h Change-Id: Ibfe69610ccd1f275f181b2bd87feece4ba221e50
This commit is contained in:
commit
22cc4d6707
|
@ -94,6 +94,7 @@ public:
|
|||
using DataLabelCompact = typename MacroAssemblerBase::DataLabelCompact;
|
||||
using Jump = typename MacroAssemblerBase::Jump;
|
||||
using PatchableJump = typename MacroAssemblerBase::PatchableJump;
|
||||
using MacroAssemblerBase::PointerSize;
|
||||
|
||||
using MacroAssemblerBase::pop;
|
||||
using MacroAssemblerBase::jump;
|
||||
|
@ -200,19 +201,19 @@ public:
|
|||
// described in terms of other macro assembly methods.
|
||||
void pop()
|
||||
{
|
||||
addPtr(TrustedImm32(sizeof(void*)), MacroAssemblerBase::stackPointerRegister);
|
||||
addPtr(TrustedImm32(PointerSize), MacroAssemblerBase::stackPointerRegister);
|
||||
}
|
||||
|
||||
void peek(RegisterID dest, int index = 0)
|
||||
{
|
||||
loadPtr(Address(MacroAssemblerBase::stackPointerRegister, (index * sizeof(void*))), dest);
|
||||
loadPtr(Address(MacroAssemblerBase::stackPointerRegister, (index * PointerSize)), dest);
|
||||
}
|
||||
|
||||
Address addressForPoke(int index)
|
||||
{
|
||||
return Address(MacroAssemblerBase::stackPointerRegister, (index * sizeof(void*)));
|
||||
return Address(MacroAssemblerBase::stackPointerRegister, (index * PointerSize));
|
||||
}
|
||||
|
||||
|
||||
void poke(RegisterID src, int index = 0)
|
||||
{
|
||||
storePtr(src, addressForPoke(index));
|
||||
|
@ -223,10 +224,12 @@ public:
|
|||
store32(value, addressForPoke(index));
|
||||
}
|
||||
|
||||
#if !defined(V4_BOOTSTRAP)
|
||||
void poke(TrustedImmPtr imm, int index = 0)
|
||||
{
|
||||
storePtr(imm, addressForPoke(index));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (CPU(X86_64) || CPU(ARM64)) && !defined(V4_BOOTSTRAP)
|
||||
void peek64(RegisterID dest, int index = 0)
|
||||
|
|
|
@ -127,6 +127,8 @@ private:
|
|||
static const ptrdiff_t REPATCH_OFFSET_CALL_TO_POINTER = -16;
|
||||
|
||||
public:
|
||||
static const int PointerSize = 8;
|
||||
|
||||
MacroAssemblerARM64()
|
||||
: m_dataMemoryTempRegister(this, dataTempRegister)
|
||||
, m_cachedMemoryTempRegister(this, memoryTempRegister)
|
||||
|
|
|
@ -46,6 +46,8 @@ protected: // the YarrJIT needs know about addressTempRegister in order to push
|
|||
inline ARMRegisters::FPSingleRegisterID fpTempRegisterAsSingle() { return ARMRegisters::asSingle(fpTempRegister); }
|
||||
|
||||
public:
|
||||
static const int PointerSize = 4;
|
||||
|
||||
MacroAssemblerARMv7()
|
||||
: m_makeJumpPatchable(false)
|
||||
{
|
||||
|
@ -1242,7 +1244,7 @@ public:
|
|||
void pop(RegisterID dest)
|
||||
{
|
||||
// store postindexed with writeback
|
||||
m_assembler.ldr(dest, ARMRegisters::sp, sizeof(void*), false, true);
|
||||
m_assembler.ldr(dest, ARMRegisters::sp, 4 /*sizeof(void*)*/, false, true);
|
||||
}
|
||||
|
||||
void push(RegisterID src)
|
||||
|
|
|
@ -37,6 +37,7 @@ namespace JSC {
|
|||
class MacroAssemblerMIPS : public AbstractMacroAssembler<MIPSAssembler> {
|
||||
public:
|
||||
typedef MIPSRegisters::FPRegisterID FPRegisterID;
|
||||
static const int PointerSize = 4;
|
||||
|
||||
MacroAssemblerMIPS()
|
||||
: m_fixedWidth(false)
|
||||
|
|
|
@ -35,6 +35,7 @@ namespace JSC {
|
|||
class MacroAssemblerX86 : public MacroAssemblerX86Common {
|
||||
public:
|
||||
static const Scale ScalePtr = TimesFour;
|
||||
static const int PointerSize = 4;
|
||||
|
||||
using MacroAssemblerX86Common::add32;
|
||||
using MacroAssemblerX86Common::and32;
|
||||
|
|
|
@ -37,6 +37,7 @@ namespace JSC {
|
|||
class MacroAssemblerX86_64 : public MacroAssemblerX86Common {
|
||||
public:
|
||||
static const Scale ScalePtr = TimesEight;
|
||||
static const int PointerSize = 8;
|
||||
|
||||
using MacroAssemblerX86Common::add32;
|
||||
using MacroAssemblerX86Common::and32;
|
||||
|
|
|
@ -95,6 +95,12 @@ bool CompilationUnit::memoryMapCode(QString *errorString)
|
|||
JSC::MacroAssemblerCodeRef codeRef = JSC::MacroAssemblerCodeRef::createSelfManagedCodeRef(JSC::MacroAssemblerCodePtr(codePtr));
|
||||
JSC::ExecutableAllocator::makeExecutable(codePtr, compiledFunction->codeSize);
|
||||
codeRefs[i] = codeRef;
|
||||
|
||||
static const bool showCode = qEnvironmentVariableIsSet("QV4_SHOW_ASM");
|
||||
if (showCode) {
|
||||
WTF::dataLogF("Mapped JIT code for %s\n", qPrintable(stringAt(compiledFunction->nameIndex)));
|
||||
disassemble(codeRef.code(), compiledFunction->codeSize, " ", WTF::dataFile());
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -535,9 +541,7 @@ void Assembler<TargetConfiguration>::returnFromFunction(IR::Ret *s, RegisterInfo
|
|||
|
||||
const int locals = stackLayout().calculateJSStackFrameSize();
|
||||
subPtr(TrustedImm32(sizeof(QV4::Value)*locals), JITTargetPlatform::LocalsRegister);
|
||||
loadPtr(Address(JITTargetPlatform::EngineRegister, targetStructureOffset(offsetof(QV4::EngineBase, current))), JITTargetPlatform::ScratchRegister);
|
||||
loadPtr(Address(JITTargetPlatform::ScratchRegister, targetStructureOffset(Heap::ExecutionContextData::baseOffset + offsetof(Heap::ExecutionContextData, engine))), JITTargetPlatform::ScratchRegister);
|
||||
storePtr(JITTargetPlatform::LocalsRegister, Address(JITTargetPlatform::ScratchRegister, targetStructureOffset(offsetof(EngineBase, jsStackTop))));
|
||||
storePtr(JITTargetPlatform::LocalsRegister, Address(JITTargetPlatform::EngineRegister, targetStructureOffset(offsetof(EngineBase, jsStackTop))));
|
||||
|
||||
leaveStandardStackFrame(regularRegistersToSave, fpRegistersToSave);
|
||||
ret();
|
||||
|
|
|
@ -1387,13 +1387,6 @@ public:
|
|||
RegisterSizeDependentOps::emitWriteBarrier(this, dest);
|
||||
}
|
||||
|
||||
void storeValue(QV4::Primitive value, RegisterID destination)
|
||||
{
|
||||
Q_UNUSED(value);
|
||||
Q_UNUSED(destination);
|
||||
Q_UNREACHABLE();
|
||||
}
|
||||
|
||||
void storeValue(QV4::Primitive value, Address destination, WriteBarrier::Type barrier)
|
||||
{
|
||||
RegisterSizeDependentOps::storeValue(this, value, destination, barrier);
|
||||
|
@ -1463,7 +1456,7 @@ public:
|
|||
template <int ArgumentIndex, typename Parameter>
|
||||
struct SizeOnStack
|
||||
{
|
||||
enum { Size = Select<ArgumentIndex >= RegisterArgumentCount, sizeof(void*), 0>::Chosen };
|
||||
enum { Size = Select<ArgumentIndex >= RegisterArgumentCount, RegisterSize, 0>::Chosen };
|
||||
};
|
||||
|
||||
template <int ArgumentIndex>
|
||||
|
|
|
@ -370,7 +370,7 @@ public:
|
|||
// There are two designated frame-pointer registers on ARM, depending on which instruction set
|
||||
// is used for the subroutine: r7 for Thumb or Thumb2, and r11 for ARM. We assign the constants
|
||||
// accordingly, and assign the locals-register to the "other" register.
|
||||
#if CPU(ARM_THUMB2)
|
||||
#if CPU(ARM_THUMB2) || defined(V4_BOOTSTRAP)
|
||||
static const RegisterID FramePointerRegister = JSC::ARMRegisters::r7;
|
||||
static const RegisterID LocalsRegister = JSC::ARMRegisters::r11;
|
||||
#else // Thumbs down
|
||||
|
@ -397,7 +397,7 @@ public:
|
|||
<< RI(JSC::ARMRegisters::r4, QStringLiteral("r4"), RI::RegularRegister, RI::CalleeSaved, RI::RegAlloc)
|
||||
<< RI(JSC::ARMRegisters::r5, QStringLiteral("r5"), RI::RegularRegister, RI::CalleeSaved, RI::Predefined)
|
||||
<< RI(JSC::ARMRegisters::r6, QStringLiteral("r6"), RI::RegularRegister, RI::CalleeSaved, RI::Predefined)
|
||||
#if !CPU(ARM_THUMB2)
|
||||
#if !CPU(ARM_THUMB2) && !defined(V4_BOOTSTRAP)
|
||||
<< RI(JSC::ARMRegisters::r7, QStringLiteral("r7"), RI::RegularRegister, RI::CalleeSaved, RI::Predefined)
|
||||
#endif
|
||||
<< RI(JSC::ARMRegisters::r8, QStringLiteral("r8"), RI::RegularRegister, RI::CalleeSaved, RI::RegAlloc)
|
||||
|
@ -405,7 +405,7 @@ public:
|
|||
<< RI(JSC::ARMRegisters::r9, QStringLiteral("r9"), RI::RegularRegister, RI::CalleeSaved, RI::RegAlloc)
|
||||
#endif
|
||||
<< RI(JSC::ARMRegisters::r10, QStringLiteral("r10"), RI::RegularRegister, RI::CalleeSaved, RI::Predefined)
|
||||
#if CPU(ARM_THUMB2)
|
||||
#if CPU(ARM_THUMB2) && !defined(V4_BOOTSTRAP)
|
||||
<< RI(JSC::ARMRegisters::r11, QStringLiteral("r11"), RI::RegularRegister, RI::CalleeSaved, RI::Predefined)
|
||||
#endif
|
||||
<< RI(JSC::ARMRegisters::d2, QStringLiteral("d2"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
|
||||
|
|
|
@ -64,6 +64,7 @@
|
|||
#include <QtCore/qwaitcondition.h>
|
||||
#include <QtCore/qloggingcategory.h>
|
||||
#include <QtQml/qqmlextensioninterface.h>
|
||||
#include <QtCore/qcryptographichash.h>
|
||||
|
||||
#include <functional>
|
||||
|
||||
|
|
|
@ -2301,7 +2301,8 @@ bool QQuickFlickable::filterMouseEvent(QQuickItem *receiver, QMouseEvent *event)
|
|||
|
||||
bool receiverDisabled = receiver && !receiver->isEnabled();
|
||||
bool stealThisEvent = d->stealMouse;
|
||||
if ((stealThisEvent || contains(localPos)) && (!receiver || !receiver->keepMouseGrab() || receiverDisabled)) {
|
||||
bool receiverKeepsGrab = receiver && (receiver->keepMouseGrab() || receiver->keepTouchGrab());
|
||||
if ((stealThisEvent || contains(localPos)) && (!receiver || !receiverKeepsGrab || receiverDisabled)) {
|
||||
QScopedPointer<QMouseEvent> mouseEvent(QQuickWindowPrivate::cloneMouseEvent(event, &localPos));
|
||||
mouseEvent->setAccepted(false);
|
||||
|
||||
|
@ -2321,7 +2322,7 @@ bool QQuickFlickable::filterMouseEvent(QQuickItem *receiver, QMouseEvent *event)
|
|||
default:
|
||||
break;
|
||||
}
|
||||
if ((receiver && stealThisEvent && !receiver->keepMouseGrab() && receiver != this) || receiverDisabled) {
|
||||
if ((receiver && stealThisEvent && !receiverKeepsGrab && receiver != this) || receiverDisabled) {
|
||||
d->clearDelayedPress();
|
||||
grabMouse();
|
||||
} else if (d->delayedPressEvent) {
|
||||
|
@ -2337,7 +2338,7 @@ bool QQuickFlickable::filterMouseEvent(QQuickItem *receiver, QMouseEvent *event)
|
|||
d->lastPosTime = -1;
|
||||
returnToBounds();
|
||||
}
|
||||
if (event->type() == QEvent::MouseButtonRelease || (receiver && receiver->keepMouseGrab() && !receiverDisabled)) {
|
||||
if (event->type() == QEvent::MouseButtonRelease || (receiverKeepsGrab && !receiverDisabled)) {
|
||||
// mouse released, or another item has claimed the grab
|
||||
d->lastPosTime = -1;
|
||||
d->clearDelayedPress();
|
||||
|
|
|
@ -746,6 +746,7 @@ void QQuickWindowPrivate::setMouseGrabber(QQuickItem *grabber)
|
|||
|
||||
qCDebug(DBG_MOUSE_TARGET) << "grabber" << q->mouseGrabberItem() << "->" << grabber;
|
||||
QQuickItem *oldGrabber = q->mouseGrabberItem();
|
||||
bool fromTouch = false;
|
||||
|
||||
if (grabber && touchMouseId != -1 && touchMouseDevice) {
|
||||
// update the touch item for mouse touch id to the new grabber
|
||||
|
@ -753,6 +754,7 @@ void QQuickWindowPrivate::setMouseGrabber(QQuickItem *grabber)
|
|||
auto point = touchMouseDevice->pointerEvent()->pointById(touchMouseId);
|
||||
if (point)
|
||||
point->setGrabber(grabber);
|
||||
fromTouch = true;
|
||||
} else {
|
||||
QQuickPointerEvent *event = QQuickPointerDevice::genericMouseDevice()->pointerEvent();
|
||||
Q_ASSERT(event->pointCount() == 1);
|
||||
|
@ -762,8 +764,11 @@ void QQuickWindowPrivate::setMouseGrabber(QQuickItem *grabber)
|
|||
if (oldGrabber) {
|
||||
QEvent e(QEvent::UngrabMouse);
|
||||
QSet<QQuickItem *> hasFiltered;
|
||||
if (!sendFilteredMouseEvent(oldGrabber->parentItem(), oldGrabber, &e, &hasFiltered))
|
||||
if (!sendFilteredMouseEvent(oldGrabber->parentItem(), oldGrabber, &e, &hasFiltered)) {
|
||||
oldGrabber->mouseUngrabEvent();
|
||||
if (fromTouch)
|
||||
oldGrabber->touchUngrabEvent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2585,28 +2590,39 @@ bool QQuickWindowPrivate::sendFilteredTouchEvent(QQuickItem *target, QQuickItem
|
|||
break;
|
||||
}
|
||||
|
||||
bool touchMouseUnset = (touchMouseId == -1);
|
||||
// Only deliver mouse event if it is the touchMouseId or it could become the touchMouseId
|
||||
if (touchMouseId == -1 || touchMouseId == tp.id()) {
|
||||
if (touchMouseUnset || touchMouseId == tp.id()) {
|
||||
// targetEvent is already transformed wrt local position, velocity, etc.
|
||||
|
||||
// FIXME: remove asTouchEvent!!!
|
||||
QScopedPointer<QMouseEvent> mouseEvent(touchToMouseEvent(t, tp, event->asTouchEvent(), item, false));
|
||||
// If a filtering item calls QQuickWindow::mouseGrabberItem(), it should
|
||||
// report the touchpoint's grabber. Whenever we send a synthetic mouse event,
|
||||
// touchMouseId and touchMouseDevice must be set, even if it's only temporarily and isn't grabbed.
|
||||
touchMouseId = tp.id();
|
||||
touchMouseDevice = event->device();
|
||||
if (target->childMouseEventFilter(item, mouseEvent.data())) {
|
||||
qCDebug(DBG_TOUCH) << " - second chance intercepted on childMouseEventFilter by " << target;
|
||||
if (t != QEvent::MouseButtonRelease) {
|
||||
qCDebug(DBG_TOUCH_TARGET) << "TP" << tp.id() << "->" << target;
|
||||
touchMouseDevice = event->device();
|
||||
if (touchMouseId == -1) {
|
||||
if (touchMouseUnset) {
|
||||
// the point was grabbed as a pure touch point before, now it will be treated as mouse
|
||||
// but the old receiver still needs to be informed
|
||||
if (auto oldGrabber = touchMouseDevice->pointerEvent()->pointById(tp.id())->grabber())
|
||||
oldGrabber->touchUngrabEvent();
|
||||
}
|
||||
touchMouseId = tp.id();
|
||||
touchMouseUnset = false; // We want to leave touchMouseId and touchMouseDevice set
|
||||
target->grabMouse();
|
||||
}
|
||||
filtered = true;
|
||||
}
|
||||
if (touchMouseUnset) {
|
||||
// Now that we're done sending a synth mouse event, and it wasn't grabbed,
|
||||
// the touchpoint is no longer acting as a synthetic mouse. Restore previous state.
|
||||
touchMouseId = -1;
|
||||
touchMouseDevice = nullptr;
|
||||
}
|
||||
// Only one event can be filtered as a mouse event.
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -353,10 +353,9 @@ QImage QQuickWidgetPrivate::grabFramebuffer()
|
|||
return renderControl->grab();
|
||||
}
|
||||
|
||||
QObject *QQuickWidgetPrivate::focusObject()
|
||||
{
|
||||
return offscreenWindow ? offscreenWindow->focusObject() : 0;
|
||||
}
|
||||
// Intentionally not overriding the QQuickWindow's focusObject.
|
||||
// Key events should go to our key event handlers, and then to the
|
||||
// QQuickWindow, not any in-scene item.
|
||||
|
||||
/*!
|
||||
\module QtQuickWidgets
|
||||
|
|
|
@ -99,8 +99,6 @@ public:
|
|||
void destroyContext();
|
||||
void handleContextCreationFailure(const QSurfaceFormat &format, bool isEs);
|
||||
|
||||
QObject *focusObject() Q_DECL_OVERRIDE;
|
||||
|
||||
#if QT_CONFIG(opengl)
|
||||
GLuint textureId() const Q_DECL_OVERRIDE;
|
||||
QImage grabFramebuffer() Q_DECL_OVERRIDE;
|
||||
|
|
|
@ -18,4 +18,7 @@ qtHaveModule(gui):qtConfig(opengl(es1|es2)?) {
|
|||
# console applications not supported
|
||||
uikit: SUBDIRS -= qmltest
|
||||
|
||||
# Restricted sub-set for now
|
||||
boot2qt: SUBDIRS = qml
|
||||
|
||||
installed_cmake.depends = cmake
|
||||
|
|
|
@ -71,7 +71,7 @@ void tst_EcmaScriptTests::runTests()
|
|||
#endif
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_EcmaScriptTests)
|
||||
QTEST_GUILESS_MAIN(tst_EcmaScriptTests)
|
||||
|
||||
#include "tst_ecmascripttests.moc"
|
||||
|
||||
|
|
|
@ -7,6 +7,9 @@ PUBLICTESTS += \
|
|||
parserstress \
|
||||
qjsvalueiterator \
|
||||
qjsonbinding \
|
||||
|
||||
!boot2qt {
|
||||
PUBLICTESTS += \
|
||||
qmlmin \
|
||||
qqmlcomponent \
|
||||
qqmlconsole \
|
||||
|
@ -25,15 +28,21 @@ PUBLICTESTS += \
|
|||
qquickfolderlistmodel \
|
||||
qqmlapplicationengine \
|
||||
qqmlsettings \
|
||||
qqmlstatemachine
|
||||
qqmlstatemachine \
|
||||
qmldiskcache
|
||||
}
|
||||
|
||||
PRIVATETESTS += \
|
||||
animation \
|
||||
qqmlcpputils \
|
||||
qqmldirparser \
|
||||
v4misc \
|
||||
|
||||
!boot2qt {
|
||||
PRIVATETESTS += \
|
||||
animation \
|
||||
qqmlecmascript \
|
||||
qqmlcontext \
|
||||
qqmlexpression \
|
||||
qqmldirparser \
|
||||
qqmlglobal \
|
||||
qqmllanguage \
|
||||
qqmlopenmetaobject \
|
||||
|
@ -57,13 +66,12 @@ PRIVATETESTS += \
|
|||
qqmltimer \
|
||||
qqmlinstantiator \
|
||||
qqmlenginecleanup \
|
||||
v4misc \
|
||||
qqmltranslation \
|
||||
qqmlimport \
|
||||
qqmlobjectmodel \
|
||||
qmldiskcache \
|
||||
qv4mm \
|
||||
ecmascripttests
|
||||
}
|
||||
|
||||
qtHaveModule(widgets) {
|
||||
PUBLICTESTS += \
|
||||
|
@ -73,7 +81,7 @@ qtHaveModule(widgets) {
|
|||
|
||||
SUBDIRS += $$PUBLICTESTS
|
||||
SUBDIRS += $$METATYPETESTS
|
||||
qtConfig(process) {
|
||||
qtConfig(process):!boot2qt {
|
||||
!contains(QT_CONFIG, no-qml-debug): SUBDIRS += debugger
|
||||
SUBDIRS += qmllint qmlplugindump
|
||||
}
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
import QtQuick 2.0
|
||||
import Test 1.0
|
||||
|
||||
Flickable {
|
||||
width: 240
|
||||
height: 320
|
||||
contentWidth: width * 1.5
|
||||
contentHeight: height * 1.5
|
||||
contentY: height * 0.25
|
||||
|
||||
Rectangle {
|
||||
id: slider
|
||||
width: 50
|
||||
height: 200
|
||||
color: "lightgray"
|
||||
border.color: drag.active ? "green" : "black"
|
||||
anchors.centerIn: parent
|
||||
radius: 4
|
||||
|
||||
TouchDragArea {
|
||||
id: drag
|
||||
objectName: "drag"
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: parent.width - 2
|
||||
height: 20
|
||||
radius: 5
|
||||
color: "darkgray"
|
||||
border.color: "black"
|
||||
x: 1
|
||||
y: Math.min(slider.height - height, Math.max(0, drag.pos.y - height / 2))
|
||||
}
|
||||
}
|
||||
}
|
|
@ -46,12 +46,109 @@
|
|||
using namespace QQuickViewTestUtil;
|
||||
using namespace QQuickVisualTestUtil;
|
||||
|
||||
// an abstract Slider which only handles touch events
|
||||
class TouchDragArea : public QQuickItem
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QPointF pos READ pos NOTIFY posChanged)
|
||||
Q_PROPERTY(bool active READ active NOTIFY activeChanged)
|
||||
Q_PROPERTY(bool keepMouseGrab READ keepMouseGrab WRITE setKeepMouseGrab NOTIFY keepMouseGrabChanged)
|
||||
Q_PROPERTY(bool keepTouchGrab READ keepTouchGrab WRITE setKeepTouchGrab NOTIFY keepTouchGrabChanged)
|
||||
|
||||
public:
|
||||
TouchDragArea(QQuickItem *parent = 0)
|
||||
: QQuickItem(parent)
|
||||
, touchEvents(0)
|
||||
, touchUpdates(0)
|
||||
, touchReleases(0)
|
||||
, ungrabs(0)
|
||||
, m_active(false)
|
||||
{
|
||||
setFlags(ItemAcceptsDrops);
|
||||
}
|
||||
|
||||
QPointF pos() const { return m_pos; }
|
||||
|
||||
bool active() const { return m_active; }
|
||||
|
||||
void setKeepMouseGrab(bool keepMouseGrab)
|
||||
{
|
||||
QQuickItem::setKeepMouseGrab(keepMouseGrab);
|
||||
emit keepMouseGrabChanged();
|
||||
}
|
||||
|
||||
void setKeepTouchGrab(bool keepTouchGrab)
|
||||
{
|
||||
QQuickItem::setKeepTouchGrab(keepTouchGrab);
|
||||
emit keepTouchGrabChanged();
|
||||
}
|
||||
|
||||
int touchEvents;
|
||||
int touchUpdates;
|
||||
int touchReleases;
|
||||
int ungrabs;
|
||||
QVector<Qt::TouchPointState> touchPointStates;
|
||||
|
||||
protected:
|
||||
void touchEvent(QTouchEvent *ev) override
|
||||
{
|
||||
QCOMPARE(ev->touchPoints().count(), 1);
|
||||
auto touchpoint = ev->touchPoints().first();
|
||||
switch (touchpoint.state()) {
|
||||
case Qt::TouchPointPressed:
|
||||
QVERIFY(!m_active);
|
||||
m_active = true;
|
||||
emit activeChanged();
|
||||
grabTouchPoints(QVector<int>() << touchpoint.id());
|
||||
break;
|
||||
case Qt::TouchPointMoved:
|
||||
++touchUpdates;
|
||||
break;
|
||||
case Qt::TouchPointReleased:
|
||||
QVERIFY(m_active);
|
||||
m_active = false;
|
||||
++touchReleases;
|
||||
emit activeChanged();
|
||||
case Qt::TouchPointStationary:
|
||||
break;
|
||||
}
|
||||
touchPointStates << touchpoint.state();
|
||||
++touchEvents;
|
||||
m_pos = touchpoint.pos();
|
||||
emit posChanged();
|
||||
}
|
||||
|
||||
void touchUngrabEvent() override
|
||||
{
|
||||
++ungrabs;
|
||||
QVERIFY(m_active);
|
||||
emit ungrabbed();
|
||||
m_active = false;
|
||||
emit activeChanged();
|
||||
}
|
||||
|
||||
signals:
|
||||
void ungrabbed();
|
||||
void posChanged();
|
||||
void keepMouseGrabChanged();
|
||||
void keepTouchGrabChanged();
|
||||
void activeChanged();
|
||||
|
||||
private:
|
||||
QPointF m_pos;
|
||||
bool m_active;
|
||||
};
|
||||
|
||||
class tst_qquickflickable : public QQmlDataTest
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
tst_qquickflickable()
|
||||
: touchDevice(QTest::createTouchDevice())
|
||||
{}
|
||||
|
||||
private slots:
|
||||
void initTestCase() override;
|
||||
void create();
|
||||
void horizontalViewportSize();
|
||||
void verticalViewportSize();
|
||||
|
@ -89,6 +186,8 @@ private slots:
|
|||
void stopAtBounds();
|
||||
void stopAtBounds_data();
|
||||
void nestedMouseAreaUsingTouch();
|
||||
void nestedSliderUsingTouch();
|
||||
void nestedSliderUsingTouch_data();
|
||||
void pressDelayWithLoader();
|
||||
void movementFromProgrammaticFlick();
|
||||
void cleanup();
|
||||
|
@ -101,9 +200,16 @@ private slots:
|
|||
void overshoot_reentrant();
|
||||
|
||||
private:
|
||||
void flickWithTouch(QQuickWindow *window, QTouchDevice *touchDevice, const QPoint &from, const QPoint &to);
|
||||
void flickWithTouch(QQuickWindow *window, const QPoint &from, const QPoint &to);
|
||||
QTouchDevice *touchDevice;
|
||||
};
|
||||
|
||||
void tst_qquickflickable::initTestCase()
|
||||
{
|
||||
QQmlDataTest::initTestCase();
|
||||
qmlRegisterType<TouchDragArea>("Test",1,0,"TouchDragArea");
|
||||
}
|
||||
|
||||
void tst_qquickflickable::cleanup()
|
||||
{
|
||||
QVERIFY(QGuiApplication::topLevelWindows().isEmpty());
|
||||
|
@ -1530,12 +1636,6 @@ void tst_qquickflickable::clickAndDragWhenTransformed()
|
|||
|
||||
void tst_qquickflickable::flickTwiceUsingTouches()
|
||||
{
|
||||
QTouchDevice *touchDevice = new QTouchDevice;
|
||||
touchDevice->setName("Fake Touchscreen");
|
||||
touchDevice->setType(QTouchDevice::TouchScreen);
|
||||
touchDevice->setCapabilities(QTouchDevice::Position);
|
||||
QWindowSystemInterface::registerTouchDevice(touchDevice);
|
||||
|
||||
QScopedPointer<QQuickView> window(new QQuickView);
|
||||
window->setSource(testFileUrl("longList.qml"));
|
||||
QTRY_COMPARE(window->status(), QQuickView::Ready);
|
||||
|
@ -1548,7 +1648,7 @@ void tst_qquickflickable::flickTwiceUsingTouches()
|
|||
QVERIFY(flickable != 0);
|
||||
|
||||
QCOMPARE(flickable->contentY(), 0.0f);
|
||||
flickWithTouch(window.data(), touchDevice, QPoint(100, 400), QPoint(100, 240));
|
||||
flickWithTouch(window.data(), QPoint(100, 400), QPoint(100, 240));
|
||||
|
||||
qreal contentYAfterFirstFlick = flickable->contentY();
|
||||
qDebug() << "contentYAfterFirstFlick " << contentYAfterFirstFlick;
|
||||
|
@ -1556,7 +1656,7 @@ void tst_qquickflickable::flickTwiceUsingTouches()
|
|||
// Wait until view stops moving
|
||||
QTRY_VERIFY(!flickable->isMoving());
|
||||
|
||||
flickWithTouch(window.data(), touchDevice, QPoint(100, 400), QPoint(100, 240));
|
||||
flickWithTouch(window.data(), QPoint(100, 400), QPoint(100, 240));
|
||||
|
||||
// In the original bug, that second flick would cause Flickable to halt immediately
|
||||
qreal contentYAfterSecondFlick = flickable->contentY();
|
||||
|
@ -1564,7 +1664,7 @@ void tst_qquickflickable::flickTwiceUsingTouches()
|
|||
QTRY_VERIFY(contentYAfterSecondFlick > (contentYAfterFirstFlick + 80.0f));
|
||||
}
|
||||
|
||||
void tst_qquickflickable::flickWithTouch(QQuickWindow *window, QTouchDevice *touchDevice, const QPoint &from, const QPoint &to)
|
||||
void tst_qquickflickable::flickWithTouch(QQuickWindow *window, const QPoint &from, const QPoint &to)
|
||||
{
|
||||
QTest::touchEvent(window, touchDevice).press(0, from, window);
|
||||
QQuickTouchUtils::flush(window);
|
||||
|
@ -1869,12 +1969,6 @@ void tst_qquickflickable::stopAtBounds()
|
|||
|
||||
void tst_qquickflickable::nestedMouseAreaUsingTouch()
|
||||
{
|
||||
QTouchDevice *touchDevice = new QTouchDevice;
|
||||
touchDevice->setName("Fake Touchscreen");
|
||||
touchDevice->setType(QTouchDevice::TouchScreen);
|
||||
touchDevice->setCapabilities(QTouchDevice::Position);
|
||||
QWindowSystemInterface::registerTouchDevice(touchDevice);
|
||||
|
||||
QScopedPointer<QQuickView> window(new QQuickView);
|
||||
window->setSource(testFileUrl("nestedmousearea.qml"));
|
||||
QTRY_COMPARE(window->status(), QQuickView::Ready);
|
||||
|
@ -1887,7 +1981,7 @@ void tst_qquickflickable::nestedMouseAreaUsingTouch()
|
|||
QVERIFY(flickable != 0);
|
||||
|
||||
QCOMPARE(flickable->contentY(), 50.0f);
|
||||
flickWithTouch(window.data(), touchDevice, QPoint(100, 300), QPoint(100, 200));
|
||||
flickWithTouch(window.data(), QPoint(100, 300), QPoint(100, 200));
|
||||
|
||||
// flickable should not have moved
|
||||
QCOMPARE(flickable->contentY(), 50.0);
|
||||
|
@ -1897,6 +1991,65 @@ void tst_qquickflickable::nestedMouseAreaUsingTouch()
|
|||
QVERIFY(nested->y() < 100.0);
|
||||
}
|
||||
|
||||
void tst_qquickflickable::nestedSliderUsingTouch_data()
|
||||
{
|
||||
QTest::addColumn<bool>("keepMouseGrab");
|
||||
QTest::addColumn<bool>("keepTouchGrab");
|
||||
QTest::addColumn<int>("updates");
|
||||
QTest::addColumn<int>("releases");
|
||||
QTest::addColumn<int>("ungrabs");
|
||||
|
||||
QTest::newRow("keepBoth") << true << true << 8 << 1 << 0;
|
||||
QTest::newRow("keepMouse") << true << false << 8 << 1 << 0;
|
||||
QTest::newRow("keepTouch") << false << true << 8 << 1 << 0;
|
||||
QTest::newRow("keepNeither") << false << false << 6 << 0 << 1;
|
||||
}
|
||||
|
||||
void tst_qquickflickable::nestedSliderUsingTouch()
|
||||
{
|
||||
QFETCH(bool, keepMouseGrab);
|
||||
QFETCH(bool, keepTouchGrab);
|
||||
QFETCH(int, updates);
|
||||
QFETCH(int, releases);
|
||||
QFETCH(int, ungrabs);
|
||||
|
||||
QQuickView *window = new QQuickView;
|
||||
QScopedPointer<QQuickView> windowPtr(window);
|
||||
windowPtr->setSource(testFileUrl("nestedSlider.qml"));
|
||||
QTRY_COMPARE(window->status(), QQuickView::Ready);
|
||||
QQuickViewTestUtil::centerOnScreen(window);
|
||||
QQuickViewTestUtil::moveMouseAway(window);
|
||||
window->show();
|
||||
QVERIFY(QTest::qWaitForWindowActive(window));
|
||||
QVERIFY(window->rootObject() != 0);
|
||||
|
||||
QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(window->rootObject());
|
||||
QVERIFY(flickable);
|
||||
|
||||
TouchDragArea *tda = flickable->findChild<TouchDragArea*>("drag");
|
||||
QVERIFY(tda);
|
||||
|
||||
// Drag down and a little to the right: flickable will steal the grab only if tda allows it
|
||||
const int dragThreshold = qApp->styleHints()->startDragDistance();
|
||||
tda->setKeepMouseGrab(keepMouseGrab);
|
||||
tda->setKeepTouchGrab(keepTouchGrab);
|
||||
QPoint p0 = tda->mapToScene(QPoint(20, 20)).toPoint();
|
||||
QTest::touchEvent(window, touchDevice).press(0, p0, window);
|
||||
QQuickTouchUtils::flush(window);
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
p0 += QPoint(dragThreshold / 6, dragThreshold / 4);
|
||||
QTest::touchEvent(window, touchDevice).move(0, p0, window);
|
||||
QQuickTouchUtils::flush(window);
|
||||
}
|
||||
QCOMPARE(tda->active(), !ungrabs);
|
||||
QTest::touchEvent(window, touchDevice).release(0, p0, window);
|
||||
QQuickTouchUtils::flush(window);
|
||||
QCOMPARE(tda->touchPointStates.first(), Qt::TouchPointPressed);
|
||||
QCOMPARE(tda->touchUpdates, updates);
|
||||
QCOMPARE(tda->touchReleases, releases);
|
||||
QCOMPARE(tda->ungrabs, ungrabs);
|
||||
}
|
||||
|
||||
// QTBUG-31328
|
||||
void tst_qquickflickable::pressDelayWithLoader()
|
||||
{
|
||||
|
|
|
@ -375,7 +375,7 @@ void tst_qquickimage::mirror()
|
|||
}
|
||||
|
||||
QImage img = expected.toImage();
|
||||
QCOMPARE(screenshots[fillMode], img);
|
||||
QCOMPARE(screenshots[fillMode].convertToFormat(img.format()), img);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -58,6 +58,7 @@ private slots:
|
|||
void grabBeforeShow();
|
||||
void reparentToNewWindow();
|
||||
void nullEngine();
|
||||
void keyEvents();
|
||||
};
|
||||
|
||||
|
||||
|
@ -337,6 +338,33 @@ void tst_qquickwidget::nullEngine()
|
|||
QVERIFY(widget.engine());
|
||||
}
|
||||
|
||||
class KeyHandlingWidget : public QQuickWidget
|
||||
{
|
||||
public:
|
||||
void keyPressEvent(QKeyEvent *e) override {
|
||||
if (e->key() == Qt::Key_A)
|
||||
ok = true;
|
||||
}
|
||||
|
||||
bool ok = false;
|
||||
};
|
||||
|
||||
void tst_qquickwidget::keyEvents()
|
||||
{
|
||||
// A QQuickWidget should behave like a normal widget when it comes to event handling.
|
||||
// Verify that key events actually reach the widget. (QTBUG-45757)
|
||||
KeyHandlingWidget widget;
|
||||
widget.setSource(testFileUrl("rectangle.qml"));
|
||||
widget.show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(widget.window(), 5000));
|
||||
|
||||
// Note: send the event to the QWindow, not the QWidget, in order
|
||||
// to simulate the full event processing chain.
|
||||
QTest::keyClick(widget.window()->windowHandle(), Qt::Key_A);
|
||||
|
||||
QTRY_VERIFY(widget.ok);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_qquickwidget)
|
||||
|
||||
#include "tst_qquickwidget.moc"
|
||||
|
|
Loading…
Reference in New Issue