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

View File

@ -298,14 +298,21 @@ QWindowSystemInterfacePrivate::GeometryChangeEvent::GeometryChangeEvent(QWindow
, window(window)
, newGeometry(newGeometry)
{
if (const QPlatformWindow *pw = window->handle())
requestedGeometry = QHighDpi::fromNativePixels(pw->QPlatformWindow::geometry(), window);
if (const QPlatformWindow *pw = window->handle()) {
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)
{
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()) {
// Persist the new geometry so that QWindow::geometry() can be queried in the resize event
window->handle()->QPlatformWindow::setGeometry(newRect);

View File

@ -577,7 +577,10 @@ void QTextMarkdownImporter::insertBlock()
QTextBlockFormat blockFormat;
if (!m_listStack.isEmpty() && !m_needsInsertList && m_listItem) {
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) {
blockFormat.setProperty(QTextFormat::BlockQuoteLevel, m_blockQuoteDepth);
@ -607,7 +610,7 @@ void QTextMarkdownImporter::insertBlock()
}
if (m_needsInsertList) {
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_needsInsertList = false;

View File

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

View File

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

View File

@ -338,7 +338,9 @@ QPlatformWindow *QWindowsIntegration::createPlatformWindow(QWindow *window) cons
QWindowsWindowData requested;
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())).
const QVariant customMarginsV = window->property("_q_windowsCustomMargins");
if (customMarginsV.isValid())

View File

@ -424,8 +424,12 @@ bool QWindowsSystemTrayIcon::winEvent(const MSG &message, long *result)
if (screen) {
emit contextMenuRequested(globalPos, screen);
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());
}
}
}
break;

View File

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

View File

@ -274,7 +274,9 @@ void QXcbWindow::create()
QXcbScreen *currentScreen = xcbScreen();
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) {
m_window = platformScreen->root();

View File

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

View File

@ -573,12 +573,32 @@ void tst_QDeadlineTimer::stdchrono()
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 system_before = system_clock::now();
QTest::qSleep(minResolution);
if (!sleepHelper(minResolution))
QSKIP("Slept too long");
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 steady_deadline = now.deadline<steady_clock>();
@ -599,35 +619,33 @@ void tst_QDeadlineTimer::stdchrono()
}
{
auto diff = duration_cast<milliseconds>(steady_after - steady_deadline);
QVERIFY2(diff.count() > minResolution/2, QByteArray::number(qint64(diff.count())));
QVERIFY2(diff.count() < 3*minResolution/2, QByteArray::number(qint64(diff.count())));
auto reference = duration_cast<milliseconds>(steady_after - steady_reference).count();
auto diff = duration_cast<milliseconds>(steady_after - steady_deadline).count();
QVERIFY2(diff > reference * 0.9 && diff < reference*1.1, QByteArray::number(qint64(diff)));
QDeadlineTimer dt_after(steady_after, timerType);
QVERIFY2(now < dt_after,
("now = " + QLocale().toString(now.deadlineNSecs()) +
"; after = " + QLocale().toString(dt_after.deadlineNSecs())).toLatin1());
diff = duration_cast<milliseconds>(steady_deadline - steady_before);
QVERIFY2(diff.count() > minResolution/2, QByteArray::number(qint64(diff.count())));
QVERIFY2(diff.count() < 3*minResolution/2, QByteArray::number(qint64(diff.count())));
reference = duration_cast<milliseconds>(steady_reference - steady_before).count();
diff = duration_cast<milliseconds>(steady_deadline - steady_before).count();
QVERIFY2(diff > reference * 0.9 && diff < reference*1.1, QByteArray::number(qint64(diff)));
QDeadlineTimer dt_before(steady_before, timerType);
QVERIFY2(now > dt_before,
("now = " + QLocale().toString(now.deadlineNSecs()) +
"; before = " + QLocale().toString(dt_before.deadlineNSecs())).toLatin1());
}
{
auto diff = duration_cast<milliseconds>(system_after - system_deadline);
QVERIFY2(diff.count() > minResolution/2, QByteArray::number(qint64(diff.count())));
QVERIFY2(diff.count() < 3*minResolution/2, QByteArray::number(qint64(diff.count())));
QDeadlineTimer dt_after(system_after, timerType);
auto reference = duration_cast<milliseconds>(system_after - system_reference).count();
auto diff = duration_cast<milliseconds>(system_after - system_deadline).count();
QVERIFY2(diff > reference * 0.9 && diff < reference*1.1, QByteArray::number(qint64(diff))); QDeadlineTimer dt_after(system_after, timerType);
QVERIFY2(now < dt_after,
("now = " + QLocale().toString(now.deadlineNSecs()) +
"; after = " + QLocale().toString(dt_after.deadlineNSecs())).toLatin1());
diff = duration_cast<milliseconds>(system_deadline - system_before);
QVERIFY2(diff.count() > minResolution/2, QByteArray::number(qint64(diff.count())));
QVERIFY2(diff.count() < 3*minResolution/2, QByteArray::number(qint64(diff.count())));
QDeadlineTimer dt_before(system_before, timerType);
reference = duration_cast<milliseconds>(system_reference - system_before).count();
diff = duration_cast<milliseconds>(steady_deadline - steady_before).count();
QVERIFY2(diff > reference * 0.9 && diff < reference*1.1, QByteArray::number(qint64(diff))); QDeadlineTimer dt_before(system_before, timerType);
QVERIFY2(now > dt_before,
("now = " + QLocale().toString(now.deadlineNSecs()) +
"; before = " + QLocale().toString(dt_before.deadlineNSecs())).toLatin1());

View File

@ -48,6 +48,7 @@ private Q_SLOTS:
void validity();
void basics();
void elapsed();
void msecsTo();
};
void tst_QElapsedTimer::statics()
@ -108,30 +109,42 @@ void tst_QElapsedTimer::elapsed()
t1.start();
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;
t2.start();
QVERIFY(t1 != t2);
QVERIFY(!(t1 == t2));
QVERIFY(t1 < t2);
QVERIFY(t1.msecsTo(t2) > 0);
QVERIFY(t1.nsecsElapsed() > 0);
QVERIFY(t1.elapsed() > 0);
// the number of elapsed nanoseconds and milliseconds should match
QVERIFY(t1.nsecsElapsed() - t1.elapsed() * 1000000 < 1000000);
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);
auto diff = t1.msecsTo(t2);
QVERIFY2(diff > 0, QString("difference t1 and t2 is %1").arg(diff).toLatin1());
diff = t2.msecsTo(t1);
QVERIFY2(diff < 0, QString("difference t2 and t1 is %1").arg(diff).toLatin1());
}
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 += \
data/thematicBreaks.md \
data/headingBulletsContinuations.md \
data/fuzz20450.md \
data/fuzz20580.md \
DEFINES += SRCDIR=\\\"$$PWD\\\"

View File

@ -57,6 +57,8 @@ private slots:
void lists();
void avoidBlankLineAtBeginning_data();
void avoidBlankLineAtBeginning();
void pathological_data();
void pathological();
};
void tst_QTextMarkdownImporter::headingBulletsContinuations()
@ -256,5 +258,27 @@ void tst_QTextMarkdownImporter::avoidBlankLineAtBeginning() // QTBUG-81060
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)
#include "tst_qtextmarkdownimporter.moc"

View File

@ -4568,7 +4568,9 @@ void tst_QGraphicsView::task255529_transformationAnchorMouseAndViewportMargins()
view.show();
qApp->setActiveWindow(&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).
#ifndef Q_OS_MAC
for (int i = 0; i < 4; ++i) {