Merge "Merge remote-tracking branch 'origin/5.14' into 5.15"
This commit is contained in:
commit
12fc3f5751
@ -84,10 +84,8 @@ enum {
|
||||
WM_QT_ACTIVATENOTIFIERS = WM_USER + 2
|
||||
};
|
||||
|
||||
// WM_QT_SENDPOSTEDEVENTS message parameter
|
||||
enum {
|
||||
WMWP_QT_TOFOREIGNLOOP = 0,
|
||||
WMWP_QT_FROMWAKEUP
|
||||
SendPostedEventsTimerId = ~1u
|
||||
};
|
||||
|
||||
class QEventDispatcherWin32Private;
|
||||
@ -100,8 +98,8 @@ LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPA
|
||||
|
||||
QEventDispatcherWin32Private::QEventDispatcherWin32Private()
|
||||
: threadId(GetCurrentThreadId()), interrupt(false), internalHwnd(0),
|
||||
getMessageHook(0), wakeUps(0), activateNotifiersPosted(false),
|
||||
winEventNotifierActivatedEvent(NULL)
|
||||
getMessageHook(0), sendPostedEventsTimerId(0), wakeUps(0),
|
||||
activateNotifiersPosted(false), winEventNotifierActivatedEvent(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
@ -129,6 +127,18 @@ void WINAPI QT_WIN_CALLBACK qt_fast_timer_proc(uint timerId, uint /*reserved*/,
|
||||
QCoreApplication::postEvent(t->dispatcher, new QTimerEvent(t->timerId));
|
||||
}
|
||||
|
||||
static inline UINT inputQueueMask()
|
||||
{
|
||||
UINT result = QS_ALLEVENTS;
|
||||
// QTBUG 28513, QTBUG-29097, QTBUG-29435: QS_TOUCH, QS_POINTER became part of
|
||||
// QS_INPUT in Windows Kit 8. They should not be used when running on pre-Windows 8.
|
||||
#if WINVER > 0x0601
|
||||
if (QOperatingSystemVersion::current() < QOperatingSystemVersion::Windows8)
|
||||
result &= ~(QS_TOUCH | QS_POINTER);
|
||||
#endif // WINVER > 0x0601
|
||||
return result;
|
||||
}
|
||||
|
||||
LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp)
|
||||
{
|
||||
if (message == WM_NCCREATE)
|
||||
@ -240,47 +250,39 @@ LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPA
|
||||
case WM_TIMER:
|
||||
Q_ASSERT(d != 0);
|
||||
|
||||
d->sendTimerEvent(wp);
|
||||
if (wp == d->sendPostedEventsTimerId)
|
||||
q->sendPostedEvents();
|
||||
else
|
||||
d->sendTimerEvent(wp);
|
||||
return 0;
|
||||
case WM_QT_SENDPOSTEDEVENTS:
|
||||
Q_ASSERT(d != 0);
|
||||
|
||||
// We send posted events manually, if the window procedure was invoked
|
||||
// by the foreign event loop (e.g. from the native modal dialog).
|
||||
q->sendPostedEvents();
|
||||
// Skip sending, if the message queue is not empty.
|
||||
// sendPostedEventsTimer will deliver posted events later.
|
||||
static const UINT mask = inputQueueMask();
|
||||
if (HIWORD(GetQueueStatus(mask)) == 0)
|
||||
q->sendPostedEvents();
|
||||
return 0;
|
||||
} // switch (message)
|
||||
|
||||
return DefWindowProc(hwnd, message, wp, lp);
|
||||
}
|
||||
|
||||
static inline UINT inputQueueMask()
|
||||
{
|
||||
UINT result = QS_ALLEVENTS;
|
||||
// QTBUG 28513, QTBUG-29097, QTBUG-29435: QS_TOUCH, QS_POINTER became part of
|
||||
// QS_INPUT in Windows Kit 8. They should not be used when running on pre-Windows 8.
|
||||
#if WINVER > 0x0601
|
||||
if (QOperatingSystemVersion::current() < QOperatingSystemVersion::Windows8)
|
||||
result &= ~(QS_TOUCH | QS_POINTER);
|
||||
#endif // WINVER > 0x0601
|
||||
return result;
|
||||
}
|
||||
|
||||
LRESULT QT_WIN_CALLBACK qt_GetMessageHook(int code, WPARAM wp, LPARAM lp)
|
||||
{
|
||||
QEventDispatcherWin32 *q = qobject_cast<QEventDispatcherWin32 *>(QAbstractEventDispatcher::instance());
|
||||
Q_ASSERT(q != 0);
|
||||
QEventDispatcherWin32Private *d = q->d_func();
|
||||
MSG *msg = reinterpret_cast<MSG *>(lp);
|
||||
static const UINT mask = inputQueueMask();
|
||||
|
||||
if (HIWORD(GetQueueStatus(mask)) == 0 && wp == PM_REMOVE) {
|
||||
// Allow posting WM_QT_SENDPOSTEDEVENTS message.
|
||||
d->wakeUps.storeRelaxed(0);
|
||||
if (!(msg->hwnd == d->internalHwnd && msg->message == WM_QT_SENDPOSTEDEVENTS)) {
|
||||
PostMessage(d->internalHwnd, WM_QT_SENDPOSTEDEVENTS,
|
||||
WMWP_QT_TOFOREIGNLOOP, 0);
|
||||
}
|
||||
if (msg->hwnd == d->internalHwnd && msg->message == WM_QT_SENDPOSTEDEVENTS
|
||||
&& wp == PM_REMOVE && d->sendPostedEventsTimerId == 0) {
|
||||
// Start a timer to deliver posted events when the message queue is emptied.
|
||||
d->sendPostedEventsTimerId = SetTimer(d->internalHwnd, SendPostedEventsTimerId,
|
||||
USER_TIMER_MINIMUM, NULL);
|
||||
}
|
||||
return d->getMessageHook ? CallNextHookEx(0, code, wp, lp) : 0;
|
||||
}
|
||||
@ -571,12 +573,15 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags)
|
||||
}
|
||||
if (haveMessage) {
|
||||
if (d->internalHwnd == msg.hwnd && msg.message == WM_QT_SENDPOSTEDEVENTS) {
|
||||
// Set result to 'true', if the message was sent by wakeUp().
|
||||
if (msg.wParam == WMWP_QT_FROMWAKEUP)
|
||||
retVal = true;
|
||||
// Set result to 'true' because the message was sent by wakeUp().
|
||||
retVal = true;
|
||||
continue;
|
||||
}
|
||||
if (msg.message == WM_TIMER) {
|
||||
// Skip timer event intended for use inside foreign loop.
|
||||
if (d->internalHwnd == msg.hwnd && msg.wParam == d->sendPostedEventsTimerId)
|
||||
continue;
|
||||
|
||||
// avoid live-lock by keeping track of the timers we've already sent
|
||||
bool found = false;
|
||||
for (int i = 0; !found && i < processedTimers.count(); ++i) {
|
||||
@ -968,8 +973,7 @@ void QEventDispatcherWin32::wakeUp()
|
||||
Q_D(QEventDispatcherWin32);
|
||||
if (d->internalHwnd && d->wakeUps.testAndSetAcquire(0, 1)) {
|
||||
// post a WM_QT_SENDPOSTEDEVENTS to this thread if there isn't one already pending
|
||||
if (!PostMessage(d->internalHwnd, WM_QT_SENDPOSTEDEVENTS,
|
||||
WMWP_QT_FROMWAKEUP, 0))
|
||||
if (!PostMessage(d->internalHwnd, WM_QT_SENDPOSTEDEVENTS, 0, 0))
|
||||
qErrnoWarning("QEventDispatcherWin32::wakeUp: Failed to post a message");
|
||||
}
|
||||
}
|
||||
@ -1015,6 +1019,10 @@ void QEventDispatcherWin32::closingDown()
|
||||
if (d->getMessageHook)
|
||||
UnhookWindowsHookEx(d->getMessageHook);
|
||||
d->getMessageHook = 0;
|
||||
|
||||
if (d->sendPostedEventsTimerId != 0)
|
||||
KillTimer(d->internalHwnd, d->sendPostedEventsTimerId);
|
||||
d->sendPostedEventsTimerId = 0;
|
||||
}
|
||||
|
||||
bool QEventDispatcherWin32::event(QEvent *e)
|
||||
@ -1056,6 +1064,14 @@ bool QEventDispatcherWin32::event(QEvent *e)
|
||||
void QEventDispatcherWin32::sendPostedEvents()
|
||||
{
|
||||
Q_D(QEventDispatcherWin32);
|
||||
|
||||
if (d->sendPostedEventsTimerId != 0)
|
||||
KillTimer(d->internalHwnd, d->sendPostedEventsTimerId);
|
||||
d->sendPostedEventsTimerId = 0;
|
||||
|
||||
// Allow posting WM_QT_SENDPOSTEDEVENTS message.
|
||||
d->wakeUps.storeRelaxed(0);
|
||||
|
||||
QCoreApplicationPrivate::sendPostedEvents(0, 0, d->threadData.loadRelaxed());
|
||||
}
|
||||
|
||||
|
@ -171,6 +171,7 @@ public:
|
||||
HHOOK getMessageHook;
|
||||
|
||||
// for controlling when to send posted events
|
||||
UINT_PTR sendPostedEventsTimerId;
|
||||
QAtomicInt wakeUps;
|
||||
|
||||
// timers
|
||||
|
@ -235,15 +235,15 @@ bool QLibraryPrivate::load_sys()
|
||||
|
||||
hnd = dlopen(QFile::encodeName(attempt), dlFlags);
|
||||
#ifdef Q_OS_ANDROID
|
||||
if (!pHnd) {
|
||||
if (!hnd) {
|
||||
auto attemptFromBundle = attempt;
|
||||
pHnd = dlopen(QFile::encodeName(attemptFromBundle.replace(QLatin1Char('/'), QLatin1Char('_'))), dlFlags);
|
||||
hnd = dlopen(QFile::encodeName(attemptFromBundle.replace(QLatin1Char('/'), QLatin1Char('_'))), dlFlags);
|
||||
}
|
||||
if (pHnd) {
|
||||
if (hnd) {
|
||||
using JniOnLoadPtr = jint (*)(JavaVM *vm, void *reserved);
|
||||
JniOnLoadPtr jniOnLoad = reinterpret_cast<JniOnLoadPtr>(dlsym(pHnd, "JNI_OnLoad"));
|
||||
if (jniOnLoad && jniOnLoad(QtAndroidPrivate::javaVM(), nullptr) == JNI_ERR) {
|
||||
dlclose(pHnd);
|
||||
dlclose(hnd);
|
||||
pHnd = nullptr;
|
||||
}
|
||||
}
|
||||
|
@ -277,10 +277,11 @@ static int fromOffsetString(QStringView offsetString, bool *valid) noexcept
|
||||
\reentrant
|
||||
\brief The QDate class provides date functions.
|
||||
|
||||
|
||||
A QDate object represents a particular date. This can be expressed as a
|
||||
calendar date, i.e. year, month, and day numbers, in the proleptic Gregorian
|
||||
calendar.
|
||||
A QDate object represents a particular day, regardless of calendar,
|
||||
locale or other settings used when creating it or supplied by the system.
|
||||
It can report the year, month and day of the month that represent the
|
||||
day with respect to the proleptic Gregorian calendar or any calendar supplied
|
||||
as a QCalendar object.
|
||||
|
||||
A QDate object is typically created by giving the year, month, and day
|
||||
numbers explicitly. Note that QDate interprets year numbers less than 100 as
|
||||
@ -1578,9 +1579,8 @@ qint64 QDate::daysTo(const QDate &d) const
|
||||
/*!
|
||||
\fn bool QDate::operator==(const QDate &d) const
|
||||
|
||||
Returns \c true if this date is equal to \a d; otherwise returns
|
||||
false.
|
||||
|
||||
Returns \c true if this date and \a d represent the same day, otherwise
|
||||
\c false.
|
||||
*/
|
||||
|
||||
/*!
|
||||
@ -1588,6 +1588,8 @@ qint64 QDate::daysTo(const QDate &d) const
|
||||
|
||||
Returns \c true if this date is different from \a d; otherwise
|
||||
returns \c false.
|
||||
|
||||
\sa operator==()
|
||||
*/
|
||||
|
||||
/*!
|
||||
|
@ -374,7 +374,7 @@ QDataStream &operator>>(QDataStream &stream, QLine &line)
|
||||
*/
|
||||
|
||||
/*!
|
||||
\enum QLineF::IntersectType
|
||||
\enum QLineF::IntersectionType
|
||||
|
||||
Describes the intersection between two lines.
|
||||
|
||||
|
@ -1229,6 +1229,11 @@ void DeleteLaterWidget::runTest()
|
||||
|
||||
QCoreApplication::processEvents();
|
||||
|
||||
// At this point, the event queue is empty. As we want a deferred
|
||||
// deletion to occur before the timer event, we should provoke the
|
||||
// event dispatcher for the next spin.
|
||||
QCoreApplication::eventDispatcher()->interrupt();
|
||||
|
||||
QVERIFY(!stillAlive); // verify at the end to make test terminate
|
||||
}
|
||||
|
||||
@ -1258,8 +1263,10 @@ void tst_QApplication::testDeleteLater()
|
||||
QObject *stillAlive = wgt->findChild<QObject*>("deleteLater");
|
||||
QVERIFY(stillAlive);
|
||||
|
||||
wgt->show();
|
||||
QCoreApplication::exec();
|
||||
|
||||
QVERIFY(wgt->isHidden());
|
||||
delete wgt;
|
||||
|
||||
}
|
||||
|
@ -82,8 +82,8 @@ public:
|
||||
|
||||
currentPos = se->contentPos();
|
||||
overshoot = se->overshootDistance();
|
||||
if (!qFuzzyCompare( overshoot.x() + 1.0, 1.0 ) ||
|
||||
!qFuzzyCompare( overshoot.y() + 1.0, 1.0 ))
|
||||
if (!qFuzzyCompare(overshoot.x() + 1.0, 1.0) ||
|
||||
!qFuzzyCompare(overshoot.y() + 1.0, 1.0))
|
||||
receivedOvershoot = true;
|
||||
return true;
|
||||
}
|
||||
@ -116,8 +116,8 @@ public:
|
||||
~tst_QScroller() { }
|
||||
|
||||
private:
|
||||
void kineticScroll( tst_QScrollerWidget *sw, QPointF from, QPoint touchStart, QPoint touchUpdate, QPoint touchEnd);
|
||||
void kineticScrollNoTest( tst_QScrollerWidget *sw, QPointF from, QPoint touchStart, QPoint touchUpdate, QPoint touchEnd);
|
||||
void kineticScroll(tst_QScrollerWidget *sw, QPointF from, QPoint touchStart, QPoint touchUpdate, QPoint touchEnd);
|
||||
void kineticScrollNoTest(tst_QScrollerWidget *sw, QPointF from, QPoint touchStart, QPoint touchUpdate, QPoint touchEnd);
|
||||
|
||||
private slots:
|
||||
void staticScrollers();
|
||||
@ -135,13 +135,13 @@ private:
|
||||
Generates touchBegin, touchUpdate and touchEnd events to trigger scrolling.
|
||||
Tests some in between states but does not wait until scrolling is finished.
|
||||
*/
|
||||
void tst_QScroller::kineticScroll( tst_QScrollerWidget *sw, QPointF from, QPoint touchStart, QPoint touchUpdate, QPoint touchEnd)
|
||||
void tst_QScroller::kineticScroll(tst_QScrollerWidget *sw, QPointF from, QPoint touchStart, QPoint touchUpdate, QPoint touchEnd)
|
||||
{
|
||||
sw->scrollPosition = from;
|
||||
sw->currentPos= from;
|
||||
|
||||
QScroller *s1 = QScroller::scroller(sw);
|
||||
QCOMPARE( s1->state(), QScroller::Inactive );
|
||||
QCOMPARE(s1->state(), QScroller::Inactive);
|
||||
|
||||
QScrollerProperties sp1 = QScroller::scroller(sw)->scrollerProperties();
|
||||
|
||||
@ -161,7 +161,7 @@ void tst_QScroller::kineticScroll( tst_QScrollerWidget *sw, QPointF from, QPoint
|
||||
(QList<QTouchEvent::TouchPoint>() << touchPoint));
|
||||
QApplication::sendEvent(sw, &touchEvent1);
|
||||
|
||||
QCOMPARE( s1->state(), QScroller::Pressed );
|
||||
QCOMPARE(s1->state(), QScroller::Pressed);
|
||||
|
||||
// send the touch update far enough to trigger a scroll
|
||||
QTest::qWait(200); // we need to wait a little or else the speed would be infinite. now we have around 500 pixel per second.
|
||||
@ -175,13 +175,13 @@ void tst_QScroller::kineticScroll( tst_QScrollerWidget *sw, QPointF from, QPoint
|
||||
(QList<QTouchEvent::TouchPoint>() << touchPoint));
|
||||
QApplication::sendEvent(sw, &touchEvent2);
|
||||
|
||||
QCOMPARE( s1->state(), QScroller::Dragging );
|
||||
QCOMPARE( sw->receivedPrepare, true );
|
||||
QCOMPARE(s1->state(), QScroller::Dragging);
|
||||
QCOMPARE(sw->receivedPrepare, true);
|
||||
|
||||
|
||||
QTRY_COMPARE( sw->receivedFirst, true );
|
||||
QCOMPARE( sw->receivedScroll, true );
|
||||
QCOMPARE( sw->receivedOvershoot, false );
|
||||
QTRY_COMPARE(sw->receivedFirst, true);
|
||||
QCOMPARE(sw->receivedScroll, true);
|
||||
QCOMPARE(sw->receivedOvershoot, false);
|
||||
|
||||
// note that the scrolling goes in a different direction than the mouse move
|
||||
QPoint calculatedPos = from.toPoint() - touchUpdate - touchStart;
|
||||
@ -204,13 +204,13 @@ void tst_QScroller::kineticScroll( tst_QScrollerWidget *sw, QPointF from, QPoint
|
||||
Generates touchBegin, touchUpdate and touchEnd events to trigger scrolling.
|
||||
This function does not have any in between tests, it does not expect the scroller to actually scroll.
|
||||
*/
|
||||
void tst_QScroller::kineticScrollNoTest( tst_QScrollerWidget *sw, QPointF from, QPoint touchStart, QPoint touchUpdate, QPoint touchEnd)
|
||||
void tst_QScroller::kineticScrollNoTest(tst_QScrollerWidget *sw, QPointF from, QPoint touchStart, QPoint touchUpdate, QPoint touchEnd)
|
||||
{
|
||||
sw->scrollPosition = from;
|
||||
sw->currentPos = from;
|
||||
|
||||
QScroller *s1 = QScroller::scroller(sw);
|
||||
QCOMPARE( s1->state(), QScroller::Inactive );
|
||||
QCOMPARE(s1->state(), QScroller::Inactive);
|
||||
|
||||
QScrollerProperties sp1 = s1->scrollerProperties();
|
||||
int fps = 60;
|
||||
@ -348,52 +348,57 @@ void tst_QScroller::scrollerProperties()
|
||||
|
||||
void tst_QScroller::scrollTo()
|
||||
{
|
||||
{
|
||||
tst_QScrollerWidget *sw = new tst_QScrollerWidget();
|
||||
sw->scrollArea = QRectF( 0, 0, 1000, 1000 );
|
||||
sw->scrollPosition = QPointF( 500, 500 );
|
||||
QScopedPointer<tst_QScrollerWidget> sw(new tst_QScrollerWidget);
|
||||
sw->show();
|
||||
QApplication::setActiveWindow(sw.data());
|
||||
if (!QTest::qWaitForWindowExposed(sw.data()) || !QTest::qWaitForWindowActive(sw.data()))
|
||||
QSKIP("Failed to show and activate window");
|
||||
|
||||
QScroller *s1 = QScroller::scroller(sw);
|
||||
QCOMPARE( s1->state(), QScroller::Inactive );
|
||||
sw->scrollArea = QRectF(0, 0, 1000, 1000);
|
||||
sw->scrollPosition = QPointF(500, 500);
|
||||
|
||||
// a normal scroll
|
||||
s1->scrollTo(QPointF(100,100), 100);
|
||||
QTest::qWait(200);
|
||||
QScroller *s1 = QScroller::scroller(sw.data());
|
||||
QCOMPARE(s1->state(), QScroller::Inactive);
|
||||
|
||||
QCOMPARE( sw->receivedPrepare, true );
|
||||
QCOMPARE( sw->receivedScroll, true );
|
||||
QCOMPARE( sw->receivedFirst, true );
|
||||
QCOMPARE( sw->receivedLast, true );
|
||||
QCOMPARE( sw->receivedOvershoot, false );
|
||||
QVERIFY(qFuzzyCompare( sw->currentPos.x(), 100 ));
|
||||
QVERIFY(qFuzzyCompare( sw->currentPos.y(), 100 ));
|
||||
// a normal scroll
|
||||
s1->scrollTo(QPointF(100,100), 100);
|
||||
QTest::qWait(200);
|
||||
|
||||
delete sw;
|
||||
}
|
||||
QTRY_COMPARE(sw->receivedPrepare, true);
|
||||
QCOMPARE(sw->receivedScroll, true);
|
||||
QCOMPARE(sw->receivedFirst, true);
|
||||
QCOMPARE(sw->receivedLast, true);
|
||||
QCOMPARE(sw->receivedOvershoot, false);
|
||||
QTRY_VERIFY(qFuzzyCompare(sw->currentPos.x(), 100));
|
||||
QVERIFY(qFuzzyCompare(sw->currentPos.y(), 100));
|
||||
}
|
||||
|
||||
void tst_QScroller::scroll()
|
||||
{
|
||||
#if QT_CONFIG(gestures) && QT_CONFIG(scroller)
|
||||
// -- good case. normal scroll
|
||||
tst_QScrollerWidget *sw = new tst_QScrollerWidget();
|
||||
QScopedPointer<tst_QScrollerWidget> sw(new tst_QScrollerWidget());
|
||||
sw->scrollArea = QRectF(0, 0, 1000, 1000);
|
||||
QScroller::grabGesture(sw, QScroller::TouchGesture);
|
||||
QScroller::grabGesture(sw.data(), QScroller::TouchGesture);
|
||||
sw->setGeometry(100, 100, 400, 300);
|
||||
sw->show();
|
||||
QApplication::setActiveWindow(sw.data());
|
||||
if (!QTest::qWaitForWindowExposed(sw.data()) || !QTest::qWaitForWindowActive(sw.data()))
|
||||
QSKIP("Failed to show and activate window");
|
||||
|
||||
QScroller *s1 = QScroller::scroller(sw);
|
||||
kineticScroll(sw, QPointF(500, 500), QPoint(0, 0), QPoint(100, 100), QPoint(200, 200));
|
||||
QScroller *s1 = QScroller::scroller(sw.data());
|
||||
kineticScroll(sw.data(), QPointF(500, 500), QPoint(0, 0), QPoint(100, 100), QPoint(200, 200));
|
||||
// now we should be scrolling
|
||||
QTRY_COMPARE( s1->state(), QScroller::Scrolling );
|
||||
QTRY_COMPARE(s1->state(), QScroller::Scrolling);
|
||||
|
||||
// wait until finished, check that no further first scroll is sent
|
||||
sw->receivedFirst = false;
|
||||
sw->receivedScroll = false;
|
||||
QTRY_VERIFY(s1->state() != QScroller::Scrolling);
|
||||
|
||||
QCOMPARE( sw->receivedFirst, false );
|
||||
QCOMPARE( sw->receivedScroll, true );
|
||||
QCOMPARE( sw->receivedLast, true );
|
||||
QCOMPARE(sw->receivedFirst, false);
|
||||
QCOMPARE(sw->receivedScroll, true);
|
||||
QCOMPARE(sw->receivedLast, true);
|
||||
QVERIFY(sw->currentPos.x() < 400);
|
||||
QVERIFY(sw->currentPos.y() < 400);
|
||||
|
||||
@ -401,26 +406,28 @@ void tst_QScroller::scroll()
|
||||
|
||||
sw->reset();
|
||||
sw->scrollArea = QRectF(0, 0, 0, 1000);
|
||||
kineticScrollNoTest(sw, QPointF(0, 500), QPoint(0, 0), QPoint(100, 0), QPoint(200, 0));
|
||||
kineticScrollNoTest(sw.data(), QPointF(0, 500), QPoint(0, 0), QPoint(100, 0), QPoint(200, 0));
|
||||
|
||||
QTRY_COMPARE(s1->state(), QScroller::Inactive);
|
||||
|
||||
QCOMPARE(sw->currentPos.x(), 0.0);
|
||||
QCOMPARE(sw->currentPos.y(), 500.0);
|
||||
|
||||
delete sw;
|
||||
#endif
|
||||
}
|
||||
|
||||
void tst_QScroller::overshoot()
|
||||
{
|
||||
#if QT_CONFIG(gestures) && QT_CONFIG(scroller)
|
||||
tst_QScrollerWidget *sw = new tst_QScrollerWidget();
|
||||
QScopedPointer<tst_QScrollerWidget> sw(new tst_QScrollerWidget);
|
||||
sw->scrollArea = QRectF(0, 0, 1000, 1000);
|
||||
QScroller::grabGesture(sw, QScroller::TouchGesture);
|
||||
QScroller::grabGesture(sw.data(), QScroller::TouchGesture);
|
||||
sw->setGeometry(100, 100, 400, 300);
|
||||
sw->show();
|
||||
QApplication::setActiveWindow(sw.data());
|
||||
if (!QTest::qWaitForWindowExposed(sw.data()) || !QTest::qWaitForWindowActive(sw.data()))
|
||||
QSKIP("Failed to show and activate window");
|
||||
|
||||
QScroller *s1 = QScroller::scroller(sw);
|
||||
QScroller *s1 = QScroller::scroller(sw.data());
|
||||
QScrollerProperties sp1 = s1->scrollerProperties();
|
||||
|
||||
sp1.setScrollMetric(QScrollerProperties::OvershootDragResistanceFactor, 0.5);
|
||||
@ -431,14 +438,14 @@ void tst_QScroller::overshoot()
|
||||
|
||||
sp1.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QVariant::fromValue(QScrollerProperties::OvershootWhenScrollable));
|
||||
s1->setScrollerProperties(sp1);
|
||||
kineticScrollNoTest(sw, QPointF(500, 500), QPoint(0, 0), QPoint(400, 0), QPoint(490, 0));
|
||||
kineticScrollNoTest(sw.data(), QPointF(500, 500), QPoint(0, 0), QPoint(400, 0), QPoint(490, 0));
|
||||
|
||||
QTRY_COMPARE(s1->state(), QScroller::Inactive);
|
||||
|
||||
//qDebug() << "Overshoot fuzzy: "<<sw->currentPos;
|
||||
QVERIFY(qFuzzyCompare( sw->currentPos.x(), 0 ));
|
||||
QVERIFY(qFuzzyCompare( sw->currentPos.y(), 500 ));
|
||||
QCOMPARE( sw->receivedOvershoot, true );
|
||||
QVERIFY(qFuzzyCompare(sw->currentPos.x(), 0));
|
||||
QVERIFY(qFuzzyCompare(sw->currentPos.y(), 500));
|
||||
QCOMPARE(sw->receivedOvershoot, true);
|
||||
|
||||
// -- try to scroll with overshoot (when scrollable bad case)
|
||||
sw->reset();
|
||||
@ -446,14 +453,14 @@ void tst_QScroller::overshoot()
|
||||
|
||||
sp1.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QVariant::fromValue(QScrollerProperties::OvershootWhenScrollable));
|
||||
s1->setScrollerProperties(sp1);
|
||||
kineticScrollNoTest(sw, QPointF(0, 500), QPoint(0, 0), QPoint(400, 0), QPoint(490, 0));
|
||||
kineticScrollNoTest(sw.data(), QPointF(0, 500), QPoint(0, 0), QPoint(400, 0), QPoint(490, 0));
|
||||
|
||||
QTRY_COMPARE(s1->state(), QScroller::Inactive);
|
||||
|
||||
//qDebug() << "Overshoot fuzzy: "<<sw->currentPos;
|
||||
QVERIFY(qFuzzyCompare( sw->currentPos.x(), 0 ));
|
||||
QVERIFY(qFuzzyCompare( sw->currentPos.y(), 500 ));
|
||||
QCOMPARE( sw->receivedOvershoot, false );
|
||||
QVERIFY(qFuzzyCompare(sw->currentPos.x(), 0));
|
||||
QVERIFY(qFuzzyCompare(sw->currentPos.y(), 500));
|
||||
QCOMPARE(sw->receivedOvershoot, false);
|
||||
|
||||
// -- try to scroll with overshoot (always on)
|
||||
sw->reset();
|
||||
@ -461,15 +468,15 @@ void tst_QScroller::overshoot()
|
||||
|
||||
sp1.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QVariant::fromValue(QScrollerProperties::OvershootAlwaysOn));
|
||||
s1->setScrollerProperties(sp1);
|
||||
kineticScrollNoTest(sw, QPointF(0, 500), QPoint(0, 0), QPoint(400, 0), QPoint(490, 0));
|
||||
kineticScrollNoTest(sw.data(), QPointF(0, 500), QPoint(0, 0), QPoint(400, 0), QPoint(490, 0));
|
||||
|
||||
QTRY_COMPARE(s1->state(), QScroller::Inactive);
|
||||
|
||||
//qDebug() << "Overshoot fuzzy: "<<sw->currentPos;
|
||||
|
||||
QVERIFY(qFuzzyCompare( sw->currentPos.x(), 0 ));
|
||||
QVERIFY(qFuzzyCompare( sw->currentPos.y(), 500 ));
|
||||
QCOMPARE( sw->receivedOvershoot, true );
|
||||
QVERIFY(qFuzzyCompare(sw->currentPos.x(), 0));
|
||||
QVERIFY(qFuzzyCompare(sw->currentPos.y(), 500));
|
||||
QCOMPARE(sw->receivedOvershoot, true);
|
||||
|
||||
// -- try to scroll with overshoot (always off)
|
||||
sw->reset();
|
||||
@ -477,13 +484,13 @@ void tst_QScroller::overshoot()
|
||||
|
||||
sp1.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QVariant::fromValue(QScrollerProperties::OvershootAlwaysOff));
|
||||
s1->setScrollerProperties(sp1);
|
||||
kineticScrollNoTest(sw, QPointF(500, 500), QPoint(0, 0), QPoint(400, 0), QPoint(490, 0));
|
||||
kineticScrollNoTest(sw.data(), QPointF(500, 500), QPoint(0, 0), QPoint(400, 0), QPoint(490, 0));
|
||||
|
||||
QTRY_COMPARE(s1->state(), QScroller::Inactive);
|
||||
|
||||
QVERIFY(qFuzzyCompare( sw->currentPos.x(), 0 ));
|
||||
QVERIFY(qFuzzyCompare( sw->currentPos.y(), 500 ));
|
||||
QCOMPARE( sw->receivedOvershoot, false );
|
||||
QVERIFY(qFuzzyCompare(sw->currentPos.x(), 0));
|
||||
QVERIFY(qFuzzyCompare(sw->currentPos.y(), 500));
|
||||
QCOMPARE(sw->receivedOvershoot, false);
|
||||
|
||||
// -- try to scroll with overshoot (always on but max overshoot = 0)
|
||||
sp1.setScrollMetric(QScrollerProperties::OvershootDragDistanceFactor, 0.0);
|
||||
@ -493,39 +500,39 @@ void tst_QScroller::overshoot()
|
||||
|
||||
sp1.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QVariant::fromValue(QScrollerProperties::OvershootAlwaysOn));
|
||||
s1->setScrollerProperties(sp1);
|
||||
kineticScrollNoTest(sw, QPointF(500, 500), QPoint(0, 0), QPoint(400, 0), QPoint(490, 0));
|
||||
kineticScrollNoTest(sw.data(), QPointF(500, 500), QPoint(0, 0), QPoint(400, 0), QPoint(490, 0));
|
||||
|
||||
QTRY_COMPARE(s1->state(), QScroller::Inactive);
|
||||
|
||||
QVERIFY(qFuzzyCompare( sw->currentPos.x(), 0 ));
|
||||
QVERIFY(qFuzzyCompare( sw->currentPos.y(), 500 ));
|
||||
QCOMPARE( sw->receivedOvershoot, false );
|
||||
|
||||
delete sw;
|
||||
QVERIFY(qFuzzyCompare(sw->currentPos.x(), 0));
|
||||
QVERIFY(qFuzzyCompare(sw->currentPos.y(), 500));
|
||||
QCOMPARE(sw->receivedOvershoot, false);
|
||||
#endif
|
||||
}
|
||||
|
||||
void tst_QScroller::multipleWindows()
|
||||
{
|
||||
#if QT_CONFIG(gestures) && QT_CONFIG(scroller)
|
||||
QScopedPointer<tst_QScrollerWidget> sw1(new tst_QScrollerWidget());
|
||||
QScopedPointer<tst_QScrollerWidget> sw1(new tst_QScrollerWidget);
|
||||
sw1->scrollArea = QRectF(0, 0, 1000, 1000);
|
||||
QScroller::grabGesture(sw1.data(), QScroller::TouchGesture);
|
||||
sw1->setGeometry(100, 100, 400, 300);
|
||||
|
||||
QScroller *s1 = QScroller::scroller(sw1.data());
|
||||
kineticScroll(sw1.data(), QPointF(500, 500), QPoint(0, 0), QPoint(100, 100), QPoint(200, 200));
|
||||
// now we should be scrolling
|
||||
QTRY_COMPARE( s1->state(), QScroller::Scrolling );
|
||||
QTRY_COMPARE(s1->state(), QScroller::Scrolling);
|
||||
|
||||
// That was fun! Do it again!
|
||||
QScopedPointer<tst_QScrollerWidget> sw2(new tst_QScrollerWidget());
|
||||
sw2->scrollArea = QRectF(0, 0, 1000, 1000);
|
||||
QScroller::grabGesture(sw2.data(), QScroller::TouchGesture);
|
||||
sw2->setGeometry(100, 100, 400, 300);
|
||||
|
||||
QScroller *s2 = QScroller::scroller(sw2.data());
|
||||
kineticScroll(sw2.data(), QPointF(500, 500), QPoint(0, 0), QPoint(100, 100), QPoint(200, 200));
|
||||
// now we should be scrolling
|
||||
QTRY_COMPARE( s2->state(), QScroller::Scrolling );
|
||||
QTRY_COMPARE(s2->state(), QScroller::Scrolling);
|
||||
|
||||
// wait for both to stop
|
||||
QTRY_VERIFY(s1->state() != QScroller::Scrolling);
|
||||
|
Loading…
Reference in New Issue
Block a user