Merge remote-tracking branch 'origin/5.14' into 5.15

Change-Id: I851c0328c3c38ea67b5ad115b205ac6a1262706e
This commit is contained in:
Qt Forward Merge Bot 2020-02-29 01:00:44 +01:00
commit 60ec012d8d
17 changed files with 141 additions and 69 deletions

View File

@ -1731,7 +1731,7 @@ void QWindow::setGeometry(const QRect &rect)
if (newScreen && isTopLevel()) if (newScreen && isTopLevel())
nativeRect = QHighDpi::toNativePixels(rect, newScreen); nativeRect = QHighDpi::toNativePixels(rect, newScreen);
else else
nativeRect = QHighDpi::toNativePixels(rect, this); nativeRect = QHighDpi::toNativeLocalPosition(rect, newScreen);
d->platformWindow->setGeometry(nativeRect); d->platformWindow->setGeometry(nativeRect);
} else { } else {
d->geometry = rect; d->geometry = rect;
@ -1782,8 +1782,12 @@ QScreen *QWindowPrivate::screenForGeometry(const QRect &newGeometry) const
QRect QWindow::geometry() const QRect QWindow::geometry() const
{ {
Q_D(const QWindow); Q_D(const QWindow);
if (d->platformWindow) if (d->platformWindow) {
return QHighDpi::fromNativePixels(d->platformWindow->geometry(), this); const auto nativeGeometry = d->platformWindow->geometry();
return isTopLevel()
? QHighDpi::fromNativePixels(nativeGeometry, this)
: QHighDpi::fromNativeLocalPosition(nativeGeometry, this);
}
return d->geometry; return d->geometry;
} }

View File

@ -298,14 +298,21 @@ QWindowSystemInterfacePrivate::GeometryChangeEvent::GeometryChangeEvent(QWindow
, window(window) , window(window)
, newGeometry(newGeometry) , newGeometry(newGeometry)
{ {
if (const QPlatformWindow *pw = window->handle()) if (const QPlatformWindow *pw = window->handle()) {
requestedGeometry = QHighDpi::fromNativePixels(pw->QPlatformWindow::geometry(), window); const auto nativeGeometry = pw->QPlatformWindow::geometry();
requestedGeometry = window->isTopLevel()
? QHighDpi::fromNativePixels(nativeGeometry, window)
: QHighDpi::fromNativeLocalPosition(nativeGeometry, window);
}
} }
QT_DEFINE_QPA_EVENT_HANDLER(void, handleGeometryChange, QWindow *window, const QRect &newRect) QT_DEFINE_QPA_EVENT_HANDLER(void, handleGeometryChange, QWindow *window, const QRect &newRect)
{ {
Q_ASSERT(window); Q_ASSERT(window);
QWindowSystemInterfacePrivate::GeometryChangeEvent *e = new QWindowSystemInterfacePrivate::GeometryChangeEvent(window, QHighDpi::fromNativePixels(newRect, window)); const auto newRectDi = window->isTopLevel()
? QHighDpi::fromNativePixels(newRect, window)
: QHighDpi::fromNativeLocalPosition(newRect, window);
auto e = new QWindowSystemInterfacePrivate::GeometryChangeEvent(window, newRectDi);
if (window->handle()) { if (window->handle()) {
// Persist the new geometry so that QWindow::geometry() can be queried in the resize event // Persist the new geometry so that QWindow::geometry() can be queried in the resize event
window->handle()->QPlatformWindow::setGeometry(newRect); window->handle()->QPlatformWindow::setGeometry(newRect);

View File

@ -577,7 +577,10 @@ void QTextMarkdownImporter::insertBlock()
QTextBlockFormat blockFormat; QTextBlockFormat blockFormat;
if (!m_listStack.isEmpty() && !m_needsInsertList && m_listItem) { if (!m_listStack.isEmpty() && !m_needsInsertList && m_listItem) {
QTextList *list = m_listStack.top(); QTextList *list = m_listStack.top();
blockFormat = list->item(list->count() - 1).blockFormat(); if (list)
blockFormat = list->item(list->count() - 1).blockFormat();
else
qWarning() << "attempted to insert into a list that no longer exists";
} }
if (m_blockQuoteDepth) { if (m_blockQuoteDepth) {
blockFormat.setProperty(QTextFormat::BlockQuoteLevel, m_blockQuoteDepth); blockFormat.setProperty(QTextFormat::BlockQuoteLevel, m_blockQuoteDepth);
@ -607,7 +610,7 @@ void QTextMarkdownImporter::insertBlock()
} }
if (m_needsInsertList) { if (m_needsInsertList) {
m_listStack.push(m_cursor->createList(m_listFormat)); m_listStack.push(m_cursor->createList(m_listFormat));
} else if (!m_listStack.isEmpty() && m_listItem) { } else if (!m_listStack.isEmpty() && m_listItem && m_listStack.top()) {
m_listStack.top()->add(m_cursor->block()); m_listStack.top()->add(m_cursor->block());
} }
m_needsInsertList = false; m_needsInsertList = false;

View File

@ -113,7 +113,7 @@ private:
#endif #endif
QString m_blockCodeLanguage; QString m_blockCodeLanguage;
QVector<int> m_nonEmptyTableCells; // in the current row QVector<int> m_nonEmptyTableCells; // in the current row
QStack<QTextList *> m_listStack; QStack<QPointer<QTextList>> m_listStack;
QStack<QTextCharFormat> m_spanFormatStack; QStack<QTextCharFormat> m_spanFormatStack;
QFont m_monoFont; QFont m_monoFont;
QPalette m_palette; QPalette m_palette;

View File

@ -202,9 +202,7 @@ public:
const QString &path) const QString &path)
: QAbstractFileEngineIterator(filters, nameFilters) : QAbstractFileEngineIterator(filters, nameFilters)
{ {
m_stack.push_back(FolderIterator::fromCache(cleanedAssetPath(path), true)); m_currentIterator = FolderIterator::fromCache(cleanedAssetPath(path), true);
if (m_stack.last()->empty())
m_stack.pop_back();
} }
QFileInfo currentFileInfo() const override QFileInfo currentFileInfo() const override
@ -228,36 +226,23 @@ public:
bool hasNext() const override bool hasNext() const override
{ {
if (m_stack.empty()) if (!m_currentIterator)
return false; return false;
if (!m_stack.last()->hasNext()) { return m_currentIterator->hasNext();
m_stack.pop_back();
return hasNext();
}
return true;
} }
QString next() override QString next() override
{ {
if (m_stack.empty()) { if (!m_currentIterator)
m_currentIterator.reset();
return {}; return {};
}
m_currentIterator = m_stack.last();
auto res = m_currentIterator->next(); auto res = m_currentIterator->next();
if (!res) if (!res)
return {}; return {};
if (res->second.type == AssetItem::Type::Folder) {
m_stack.push_back(FolderIterator::fromCache(cleanedAssetPath(currentFilePath()), true));
if (m_stack.last()->empty())
m_stack.pop_back();
}
return res->first; return res->first;
} }
private: private:
mutable QSharedPointer<FolderIterator> m_currentIterator; QSharedPointer<FolderIterator> m_currentIterator;
mutable QVector<QSharedPointer<FolderIterator>> m_stack;
}; };
class AndroidAbstractFileEngine: public QAbstractFileEngine class AndroidAbstractFileEngine: public QAbstractFileEngine

View File

@ -338,7 +338,9 @@ QPlatformWindow *QWindowsIntegration::createPlatformWindow(QWindow *window) cons
QWindowsWindowData requested; QWindowsWindowData requested;
requested.flags = window->flags(); requested.flags = window->flags();
requested.geometry = QHighDpi::toNativePixels(window->geometry(), window); requested.geometry = window->isTopLevel()
? QHighDpi::toNativePixels(window->geometry(), window)
: QHighDpi::toNativeLocalPosition(window->geometry(), window);
// Apply custom margins (see QWindowsWindow::setCustomMargins())). // Apply custom margins (see QWindowsWindow::setCustomMargins())).
const QVariant customMarginsV = window->property("_q_windowsCustomMargins"); const QVariant customMarginsV = window->property("_q_windowsCustomMargins");
if (customMarginsV.isValid()) if (customMarginsV.isValid())

View File

@ -424,8 +424,12 @@ bool QWindowsSystemTrayIcon::winEvent(const MSG &message, long *result)
if (screen) { if (screen) {
emit contextMenuRequested(globalPos, screen); emit contextMenuRequested(globalPos, screen);
emit activated(Context); emit activated(Context);
if (m_menu) if (m_menu) {
// Set the foreground window to the controlling window so that clicking outside
// of the menu or window will cause the menu to close
SetForegroundWindow(m_hwnd);
m_menu->trackPopupMenu(message.hwnd, globalPos.x(), globalPos.y()); m_menu->trackPopupMenu(message.hwnd, globalPos.x(), globalPos.y());
}
} }
} }
break; break;

View File

@ -1954,10 +1954,8 @@ void QWindowsWindow::checkForScreenChanged(ScreenChangeMode mode)
qCDebug(lcQpaWindows).noquote().nospace() << __FUNCTION__ qCDebug(lcQpaWindows).noquote().nospace() << __FUNCTION__
<< ' ' << window() << " \"" << (currentScreen ? currentScreen->name() : QString()) << ' ' << window() << " \"" << (currentScreen ? currentScreen->name() : QString())
<< "\"->\"" << newScreen->name() << '"'; << "\"->\"" << newScreen->name() << '"';
if (mode == FromGeometryChange)
setFlag(SynchronousGeometryChangeEvent);
updateFullFrameMargins(); updateFullFrameMargins();
QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->screen()); QWindowSystemInterface::handleWindowScreenChanged<QWindowSystemInterface::SynchronousDelivery>(window(), newScreen->screen());
} }
void QWindowsWindow::handleGeometryChange() void QWindowsWindow::handleGeometryChange()

View File

@ -274,7 +274,9 @@ void QXcbWindow::create()
QXcbScreen *currentScreen = xcbScreen(); QXcbScreen *currentScreen = xcbScreen();
QXcbScreen *platformScreen = parent() ? parentScreen() : initialScreen(); QXcbScreen *platformScreen = parent() ? parentScreen() : initialScreen();
QRect rect = QHighDpi::toNativePixels(window()->geometry(), platformScreen); QRect rect = parent()
? QHighDpi::toNativeLocalPosition(window()->geometry(), platformScreen)
: QHighDpi::toNativePixels(window()->geometry(), platformScreen);
if (type == Qt::Desktop) { if (type == Qt::Desktop) {
m_window = platformScreen->root(); m_window = platformScreen->root();

View File

@ -131,6 +131,8 @@ void WriteImports::acceptCustomWidget(DomCustomWidget *node)
output << "import " << className << '\n'; output << "import " << className << '\n';
} else { // When we do have elementHeader, we know it's a relative import. } else { // When we do have elementHeader, we know it's a relative import.
QString modulePath = node->elementHeader()->text(); QString modulePath = node->elementHeader()->text();
// Replace the '/' by '.'
modulePath.replace(QLatin1Char('/'), QLatin1Char('.'));
// '.h' is added by default on headers for <customwidget> // '.h' is added by default on headers for <customwidget>
if (modulePath.endsWith(QLatin1String(".h"))) if (modulePath.endsWith(QLatin1String(".h")))
modulePath.chop(2); modulePath.chop(2);

View File

@ -573,12 +573,32 @@ void tst_QDeadlineTimer::stdchrono()
QCOMPARE(deadline.remainingTimeAsDuration(), nanoseconds::zero()); QCOMPARE(deadline.remainingTimeAsDuration(), nanoseconds::zero());
/*
Call QTest::qSleep, and return true if the time actually slept is
within \a deviationPercent percent of the requested sleep time.
Otherwise, return false, in which case the test should to abort.
*/
auto sleepHelper = [](int ms, int deviationPercent = 10) -> bool {
auto before = steady_clock::now();
QTest::qSleep(ms);
auto after = steady_clock::now();
auto diff = duration_cast<milliseconds>(after - before).count();
bool inRange = qAbs(diff - ms) < ms * deviationPercent/100.0;
if (!inRange)
qWarning() << "sleeping" << diff << "instead of" << ms << inRange;
return inRange;
};
auto steady_before = steady_clock::now(); auto steady_before = steady_clock::now();
auto system_before = system_clock::now(); auto system_before = system_clock::now();
QTest::qSleep(minResolution); if (!sleepHelper(minResolution))
QSKIP("Slept too long");
auto now = QDeadlineTimer::current(timerType); auto now = QDeadlineTimer::current(timerType);
QTest::qSleep(minResolution); auto steady_reference = steady_clock::now();
auto system_reference = system_clock::now();
if (!sleepHelper(minResolution))
QSKIP("Slept too long");
auto sampling_start = steady_clock::now(); auto sampling_start = steady_clock::now();
auto steady_deadline = now.deadline<steady_clock>(); auto steady_deadline = now.deadline<steady_clock>();
@ -599,35 +619,33 @@ void tst_QDeadlineTimer::stdchrono()
} }
{ {
auto diff = duration_cast<milliseconds>(steady_after - steady_deadline); auto reference = duration_cast<milliseconds>(steady_after - steady_reference).count();
QVERIFY2(diff.count() > minResolution/2, QByteArray::number(qint64(diff.count()))); auto diff = duration_cast<milliseconds>(steady_after - steady_deadline).count();
QVERIFY2(diff.count() < 3*minResolution/2, QByteArray::number(qint64(diff.count()))); QVERIFY2(diff > reference * 0.9 && diff < reference*1.1, QByteArray::number(qint64(diff)));
QDeadlineTimer dt_after(steady_after, timerType); QDeadlineTimer dt_after(steady_after, timerType);
QVERIFY2(now < dt_after, QVERIFY2(now < dt_after,
("now = " + QLocale().toString(now.deadlineNSecs()) + ("now = " + QLocale().toString(now.deadlineNSecs()) +
"; after = " + QLocale().toString(dt_after.deadlineNSecs())).toLatin1()); "; after = " + QLocale().toString(dt_after.deadlineNSecs())).toLatin1());
diff = duration_cast<milliseconds>(steady_deadline - steady_before); reference = duration_cast<milliseconds>(steady_reference - steady_before).count();
QVERIFY2(diff.count() > minResolution/2, QByteArray::number(qint64(diff.count()))); diff = duration_cast<milliseconds>(steady_deadline - steady_before).count();
QVERIFY2(diff.count() < 3*minResolution/2, QByteArray::number(qint64(diff.count()))); QVERIFY2(diff > reference * 0.9 && diff < reference*1.1, QByteArray::number(qint64(diff)));
QDeadlineTimer dt_before(steady_before, timerType); QDeadlineTimer dt_before(steady_before, timerType);
QVERIFY2(now > dt_before, QVERIFY2(now > dt_before,
("now = " + QLocale().toString(now.deadlineNSecs()) + ("now = " + QLocale().toString(now.deadlineNSecs()) +
"; before = " + QLocale().toString(dt_before.deadlineNSecs())).toLatin1()); "; before = " + QLocale().toString(dt_before.deadlineNSecs())).toLatin1());
} }
{ {
auto diff = duration_cast<milliseconds>(system_after - system_deadline); auto reference = duration_cast<milliseconds>(system_after - system_reference).count();
QVERIFY2(diff.count() > minResolution/2, QByteArray::number(qint64(diff.count()))); auto diff = duration_cast<milliseconds>(system_after - system_deadline).count();
QVERIFY2(diff.count() < 3*minResolution/2, QByteArray::number(qint64(diff.count()))); QVERIFY2(diff > reference * 0.9 && diff < reference*1.1, QByteArray::number(qint64(diff))); QDeadlineTimer dt_after(system_after, timerType);
QDeadlineTimer dt_after(system_after, timerType);
QVERIFY2(now < dt_after, QVERIFY2(now < dt_after,
("now = " + QLocale().toString(now.deadlineNSecs()) + ("now = " + QLocale().toString(now.deadlineNSecs()) +
"; after = " + QLocale().toString(dt_after.deadlineNSecs())).toLatin1()); "; after = " + QLocale().toString(dt_after.deadlineNSecs())).toLatin1());
diff = duration_cast<milliseconds>(system_deadline - system_before); reference = duration_cast<milliseconds>(system_reference - system_before).count();
QVERIFY2(diff.count() > minResolution/2, QByteArray::number(qint64(diff.count()))); diff = duration_cast<milliseconds>(steady_deadline - steady_before).count();
QVERIFY2(diff.count() < 3*minResolution/2, QByteArray::number(qint64(diff.count()))); QVERIFY2(diff > reference * 0.9 && diff < reference*1.1, QByteArray::number(qint64(diff))); QDeadlineTimer dt_before(system_before, timerType);
QDeadlineTimer dt_before(system_before, timerType);
QVERIFY2(now > dt_before, QVERIFY2(now > dt_before,
("now = " + QLocale().toString(now.deadlineNSecs()) + ("now = " + QLocale().toString(now.deadlineNSecs()) +
"; before = " + QLocale().toString(dt_before.deadlineNSecs())).toLatin1()); "; before = " + QLocale().toString(dt_before.deadlineNSecs())).toLatin1());

View File

@ -48,6 +48,7 @@ private Q_SLOTS:
void validity(); void validity();
void basics(); void basics();
void elapsed(); void elapsed();
void msecsTo();
}; };
void tst_QElapsedTimer::statics() void tst_QElapsedTimer::statics()
@ -108,30 +109,42 @@ void tst_QElapsedTimer::elapsed()
t1.start(); t1.start();
QTest::qSleep(2*minResolution); QTest::qSleep(2*minResolution);
auto nsecs = t1.nsecsElapsed();
auto msecs = t1.elapsed();
QVERIFY(nsecs > 0);
QVERIFY(msecs > 0);
// the number of elapsed nanoseconds and milliseconds should match
QVERIFY(nsecs - msecs * 1000000 < 1000000);
if (msecs > 8 * minResolution)
QSKIP("Sampling timer took too long, aborting test");
QVERIFY(t1.hasExpired(minResolution));
QVERIFY(!t1.hasExpired(8*minResolution));
QVERIFY(!t1.hasExpired(-1));
qint64 elapsed = t1.restart();
QVERIFY(elapsed >= msecs);
QVERIFY(elapsed < msecs + 3*minResolution);
}
void tst_QElapsedTimer::msecsTo()
{
QElapsedTimer t1;
t1.start();
QTest::qSleep(minResolution);
QElapsedTimer t2; QElapsedTimer t2;
t2.start(); t2.start();
QVERIFY(t1 != t2); QVERIFY(t1 != t2);
QVERIFY(!(t1 == t2)); QVERIFY(!(t1 == t2));
QVERIFY(t1 < t2); QVERIFY(t1 < t2);
QVERIFY(t1.msecsTo(t2) > 0);
QVERIFY(t1.nsecsElapsed() > 0); auto diff = t1.msecsTo(t2);
QVERIFY(t1.elapsed() > 0); QVERIFY2(diff > 0, QString("difference t1 and t2 is %1").arg(diff).toLatin1());
// the number of elapsed nanoseconds and milliseconds should match diff = t2.msecsTo(t1);
QVERIFY(t1.nsecsElapsed() - t1.elapsed() * 1000000 < 1000000); QVERIFY2(diff < 0, QString("difference t2 and t1 is %1").arg(diff).toLatin1());
QVERIFY(t1.hasExpired(minResolution));
QVERIFY(!t1.hasExpired(8*minResolution));
QVERIFY(!t2.hasExpired(minResolution));
QVERIFY(!t1.hasExpired(-1));
QVERIFY(!t2.hasExpired(-1));
qint64 elapsed = t1.restart();
QVERIFY(elapsed > minResolution);
QVERIFY(elapsed < 3*minResolution);
qint64 diff = t2.msecsTo(t1);
QVERIFY(diff < minResolution);
} }
QTEST_MAIN(tst_QElapsedTimer); QTEST_MAIN(tst_QElapsedTimer);

View File

@ -0,0 +1,5 @@
<t><EFBFBD>
* <20>
<09>
* <20>

View File

@ -0,0 +1 @@
| --:| <?`?><?|`

View File

@ -5,5 +5,7 @@ SOURCES += tst_qtextmarkdownimporter.cpp
TESTDATA += \ TESTDATA += \
data/thematicBreaks.md \ data/thematicBreaks.md \
data/headingBulletsContinuations.md \ data/headingBulletsContinuations.md \
data/fuzz20450.md \
data/fuzz20580.md \
DEFINES += SRCDIR=\\\"$$PWD\\\" DEFINES += SRCDIR=\\\"$$PWD\\\"

View File

@ -57,6 +57,8 @@ private slots:
void lists(); void lists();
void avoidBlankLineAtBeginning_data(); void avoidBlankLineAtBeginning_data();
void avoidBlankLineAtBeginning(); void avoidBlankLineAtBeginning();
void pathological_data();
void pathological();
}; };
void tst_QTextMarkdownImporter::headingBulletsContinuations() void tst_QTextMarkdownImporter::headingBulletsContinuations()
@ -256,5 +258,27 @@ void tst_QTextMarkdownImporter::avoidBlankLineAtBeginning() // QTBUG-81060
QCOMPARE(i, expectedNumberOfParagraphs); QCOMPARE(i, expectedNumberOfParagraphs);
} }
void tst_QTextMarkdownImporter::pathological_data()
{
QTest::addColumn<QString>("warning");
QTest::newRow("fuzz20450") << "attempted to insert into a list that no longer exists";
QTest::newRow("fuzz20580") << "";
}
void tst_QTextMarkdownImporter::pathological() // avoid crashing on crazy input
{
QFETCH(QString, warning);
QString filename = QLatin1String("data/") + QTest::currentDataTag() + QLatin1String(".md");
QFile f(QFINDTESTDATA(filename));
QVERIFY(f.open(QFile::ReadOnly));
#ifdef QT_NO_DEBUG
Q_UNUSED(warning)
#else
if (!warning.isEmpty())
QTest::ignoreMessage(QtWarningMsg, warning.toLatin1());
#endif
QTextDocument().setMarkdown(f.readAll());
}
QTEST_MAIN(tst_QTextMarkdownImporter) QTEST_MAIN(tst_QTextMarkdownImporter)
#include "tst_qtextmarkdownimporter.moc" #include "tst_qtextmarkdownimporter.moc"

View File

@ -4568,7 +4568,9 @@ void tst_QGraphicsView::task255529_transformationAnchorMouseAndViewportMargins()
view.show(); view.show();
qApp->setActiveWindow(&view); qApp->setActiveWindow(&view);
QVERIFY(QTest::qWaitForWindowExposed(&view)); QVERIFY(QTest::qWaitForWindowExposed(&view));
QVERIFY(QTest::qWaitForWindowActive(&view)); const bool isActiveWindow = QTest::qWaitForWindowActive(&view);
if (!isActiveWindow)
QSKIP("Window activation failed, skipping test", Abort);
// This is highly unstable (observed to pass on Windows and some Linux configurations). // This is highly unstable (observed to pass on Windows and some Linux configurations).
#ifndef Q_OS_MAC #ifndef Q_OS_MAC
for (int i = 0; i < 4; ++i) { for (int i = 0; i < 4; ++i) {