From 47aad8f1cc24f47b6c3b6b4888c56710887d6eb7 Mon Sep 17 00:00:00 2001 From: Kai Uwe Broulik Date: Thu, 28 Apr 2016 15:59:28 +0200 Subject: [PATCH 01/87] Android: show status bar for any window state except fullscreen This fixes the status bar not re-appearing when a window is reset to Qt::WindowNoState Task-number: QTBUG-37830 Change-Id: Iaef99221993ddf17b9da5b48796143abbcd98c01 Reviewed-by: Risto Avila Reviewed-by: BogDan Vatra --- src/plugins/platforms/android/qandroidplatformwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/android/qandroidplatformwindow.cpp b/src/plugins/platforms/android/qandroidplatformwindow.cpp index b39695b0ef9..7e46e5f09ee 100644 --- a/src/plugins/platforms/android/qandroidplatformwindow.cpp +++ b/src/plugins/platforms/android/qandroidplatformwindow.cpp @@ -149,7 +149,7 @@ void QAndroidPlatformWindow::updateStatusBarVisibility() if (!isNonRegularWindow) { if (m_windowState & Qt::WindowFullScreen) QtAndroid::hideStatusBar(); - else if (m_windowState & Qt::WindowMaximized) + else QtAndroid::showStatusBar(); } } From 5971b88ecd08a81720c3556029cecd35b0cf2cb5 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 1 Sep 2016 10:48:06 +0200 Subject: [PATCH 02/87] configure.exe: Write MSVC compiler version to qconfig.pri Backport a feature of the new configure system setting the variables QT_CL_MAJOR_VERSION, QT_CL_MINOR_VERSION, QT_CL_PATCH_VERSION similarly to the existing variables for gcc. This allows for disabling optimizations depending on the compiler version. Task-number: QTBUG-55238 Change-Id: If2349b008c1049e2ab98a5c1160b244a6e8937a8 Reviewed-by: Oswald Buddenhagen --- tools/configure/configureapp.cpp | 10 ++++++++++ tools/configure/environment.cpp | 24 ++++++++++++++++++++++++ tools/configure/environment.h | 1 + 3 files changed, 35 insertions(+) diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index f2b54f57f29..88dcd8170b4 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -314,6 +314,12 @@ Configure::Configure(int& argc, char** argv) : verbose(0) dictionary["QT_GCC_MAJOR_VERSION"] = parts.value(0, zero); dictionary["QT_GCC_MINOR_VERSION"] = parts.value(1, zero); dictionary["QT_GCC_PATCH_VERSION"] = parts.value(2, zero); + } else if (dictionary["QMAKESPEC"].contains(QString("msvc"))) { + const QString zero = QStringLiteral("0"); + const QStringList parts = Environment::msvcVersion().split(QLatin1Char('.')); + dictionary["QT_CL_MAJOR_VERSION"] = parts.value(0, zero); + dictionary["QT_CL_MINOR_VERSION"] = parts.value(1, zero); + dictionary["QT_CL_PATCH_VERSION"] = parts.value(2, zero); } } @@ -3629,6 +3635,10 @@ void Configure::generateQConfigPri() configStream << "QT_GCC_MAJOR_VERSION = " << dictionary["QT_GCC_MAJOR_VERSION"] << endl << "QT_GCC_MINOR_VERSION = " << dictionary["QT_GCC_MINOR_VERSION"] << endl << "QT_GCC_PATCH_VERSION = " << dictionary["QT_GCC_PATCH_VERSION"] << endl; + } else if (!dictionary["QT_CL_MAJOR_VERSION"].isEmpty()) { + configStream << "QT_CL_MAJOR_VERSION = " << dictionary["QT_CL_MAJOR_VERSION"] << endl + << "QT_CL_MINOR_VERSION = " << dictionary["QT_CL_MINOR_VERSION"] << endl + << "QT_CL_PATCH_VERSION = " << dictionary["QT_CL_PATCH_VERSION"] << endl; } if (dictionary.value("XQMAKESPEC").startsWith("wince")) { diff --git a/tools/configure/environment.cpp b/tools/configure/environment.cpp index 5e28fda11dc..10cf5ace2a1 100644 --- a/tools/configure/environment.cpp +++ b/tools/configure/environment.cpp @@ -169,6 +169,30 @@ QString Environment::gccVersion() return version; } +QString Environment::msvcVersion() +{ + int returnValue = 0; + // Extract version from standard error output of "cl /?" + const QString command = QFile::decodeName(qgetenv("ComSpec")) + + QLatin1String(" /c ") + QLatin1String(compilerInfo(CC_MSVC2015)->executable) + + QLatin1String(" /? 2>&1"); + QString version = execute(command, &returnValue); + if (returnValue != 0) { + cout << "Could not get cl version" << returnValue << qPrintable(version) << '\n';; + version.clear(); + } else { + QRegExp versionRegexp(QStringLiteral("^.*Compiler Version ([0-9.]+) for.*$")); + Q_ASSERT(versionRegexp.isValid()); + if (versionRegexp.exactMatch(version)) { + version = versionRegexp.cap(1); + } else { + cout << "Unable to determine cl version from the output of \"" + << qPrintable(command) << "\"\n"; + } + } + return version; +} + /*! Returns the enum of the compiler which was detected on the system. The compilers are detected in the order as entered into the diff --git a/tools/configure/environment.h b/tools/configure/environment.h index 927c3e294f0..d096782e700 100644 --- a/tools/configure/environment.h +++ b/tools/configure/environment.h @@ -57,6 +57,7 @@ public: static QString detectQMakeSpec(); static Compiler compilerFromQMakeSpec(const QString &qmakeSpec); static QString gccVersion(); + static QString msvcVersion(); static int execute(QStringList arguments, const QStringList &additionalEnv, const QStringList &removeEnv); static QString execute(const QString &command, int *returnCode = 0); From 75ef5859b6b249726e10a0d407d8d86d2f6e25a1 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 2 Sep 2016 15:42:53 +0200 Subject: [PATCH 03/87] Fix compilation of findfiles examples with QT_NO_CLIPBOARD Amends change d1a30be5abcc2d5e5340866434b2691275a135a6. Task-number: QTBUG-55661 Change-Id: Ib7b1b4afd71b3c35493c15c8bf3e2570e321c986 Reviewed-by: Marc Mutz --- examples/widgets/dialogs/findfiles/window.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/examples/widgets/dialogs/findfiles/window.cpp b/examples/widgets/dialogs/findfiles/window.cpp index ce53dd8c839..1c590545245 100644 --- a/examples/widgets/dialogs/findfiles/window.cpp +++ b/examples/widgets/dialogs/findfiles/window.cpp @@ -294,15 +294,19 @@ void Window::contextMenu(const QPoint &pos) if (!item) return; QMenu menu; +#ifndef QT_NO_CLIPBOARD QAction *copyAction = menu.addAction("Copy Name"); +#endif QAction *openAction = menu.addAction("Open"); QAction *action = menu.exec(filesTable->mapToGlobal(pos)); if (!action) return; const QString fileName = fileNameOfItem(item); - if (action == copyAction) - QGuiApplication::clipboard()->setText(QDir::toNativeSeparators(fileName)); - else if (action == openAction) + if (action == openAction) openFile(fileName); +#ifndef QT_NO_CLIPBOARD + else if (action == copyAction) + QGuiApplication::clipboard()->setText(QDir::toNativeSeparators(fileName)); +#endif } //! [16] From c8a6b4278b04ff3ffb4484a3cf17cf4638dbadb4 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Mon, 22 Aug 2016 12:07:16 +0200 Subject: [PATCH 04/87] winrt: Exclude user events when adding/removing windows Handling user events while creating a window can cause problems and crashes as the event tries to access non initialized parts of the window itself being created. Hence exclude user input events at that time and have them handled when the event loop checks for them regularly. Change-Id: I2a78efd619250be8f6f2e737ed78e39481a4cf76 Reviewed-by: Oliver Wolff Reviewed-by: Friedemann Kleint --- src/plugins/platforms/winrt/qwinrtscreen.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp index dd2ebee3d54..3be17b0180d 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.cpp +++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp @@ -767,7 +767,7 @@ void QWinRTScreen::addWindow(QWindow *window) updateWindowTitle(window->title()); QWindowSystemInterface::handleWindowActivated(window, Qt::OtherFocusReason); handleExpose(); - QWindowSystemInterface::flushWindowSystemEvents(); + QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents); #if _MSC_VER >= 1900 && !defined(QT_NO_DRAGANDDROP) QWinRTDrag::instance()->setDropTarget(window); @@ -785,7 +785,7 @@ void QWinRTScreen::removeWindow(QWindow *window) if (wasTopWindow) QWindowSystemInterface::handleWindowActivated(Q_NULLPTR, Qt::OtherFocusReason); handleExpose(); - QWindowSystemInterface::flushWindowSystemEvents(); + QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents); #if _MSC_VER >= 1900 && !defined(QT_NO_DRAGANDDROP) if (wasTopWindow) QWinRTDrag::instance()->setDropTarget(topWindow()); From a0d3455ee396b1df5d10a0dc1ee84950fc3635a6 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Fri, 12 Aug 2016 07:08:33 +0200 Subject: [PATCH 05/87] Taking trailing whitespace into account when shaping lines The calculated end position of script lines, consisting of nothing but trailing spaces, is lower than the start position. This results in not shaping those script lines. Task-number: QTBUG-55255 Change-Id: Ib70c1a800d2f70b7f61e3d05c10618e275f45f12 Reviewed-by: Konstantin Ritt Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/text/qtextengine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 17a91f5a6a5..3b503765042 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -922,7 +922,7 @@ void QTextEngine::shapeLine(const QScriptLine &line) if (item == -1) return; - const int end = findItem(line.from + line.length - 1, item); + const int end = findItem(line.from + line.length + line.trailingSpaces - 1, item); for ( ; item <= end; ++item) { QScriptItem &si = layoutData->items[item]; if (si.analysis.flags == QScriptAnalysis::Tab) { From bd9f3c50df9ad782b49eb47edf6264f8c4e8ac74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Martins?= Date: Tue, 23 Aug 2016 20:42:42 +0100 Subject: [PATCH 06/87] QToolButton: fix read of uninitialized variable Calling style() can trigger a call into user code which can read the tool button's members before they are initialized ==3566== Conditional jump or move depends on uninitialised value(s) ==3566== at 0x421C39: MyProxyStyle::pixelMetric(QStyle::PixelMetric, QStyleOption const*, QWidget const*) const (MyProxyStyle.cpp:635) ==3566== by 0x504B8B1: QRenderRule::QRenderRule(QVector const&, QObject const*) (qstylesheetstyle.cpp:1004) ==3566== by 0x504D084: QStyleSheetStyle::renderRule(QObject const*, int, unsigned long long) const (qstylesheetstyle.cpp:1747) ==3566== by 0x504D4A5: QStyleSheetStyle::renderRule(QObject const*, QStyleOption const*, int) const (qstylesheetstyle.cpp:2023) ==3566== by 0x504FF02: QStyleSheetStyle::styleHint(QStyle::StyleHint, QStyleOption const*, QWidget const*, QStyleHintReturn*) const (qstylesheetstyle.cpp:5146) ==3566== by 0x517B2D0: QToolButtonPrivate::init() (qtoolbutton.cpp:193) Change-Id: I56bca15d3ec7cd7b255a83dca786532a2f9b9b48 Reviewed-by: David Faure --- src/widgets/widgets/qtoolbutton.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/widgets/widgets/qtoolbutton.cpp b/src/widgets/widgets/qtoolbutton.cpp index f8b2dff720f..998dad13728 100644 --- a/src/widgets/widgets/qtoolbutton.cpp +++ b/src/widgets/widgets/qtoolbutton.cpp @@ -190,7 +190,6 @@ QToolButton::QToolButton(QWidget * parent) void QToolButtonPrivate::init() { Q_Q(QToolButton); - delay = q->style()->styleHint(QStyle::SH_ToolButton_PopupDelay, 0, q); defaultAction = 0; #ifndef QT_NO_TOOLBAR if (qobject_cast(parent)) @@ -216,7 +215,7 @@ void QToolButtonPrivate::init() #endif setLayoutItemMargins(QStyle::SE_ToolButtonLayoutItem); - + delay = q->style()->styleHint(QStyle::SH_ToolButton_PopupDelay, 0, q); } /*! From 43a710df639c695f4c87e4857b8e8b045ab3df76 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Mon, 5 Sep 2016 09:14:05 +0200 Subject: [PATCH 07/87] MySQL: Fix MySQL plugin build with MySQL 5.0 Task-number: QTBUG-55544 Change-Id: Iff4e3109f475f9c3c8764fc6741b8d0547769ba2 Reviewed-by: Jesus Fernandez Reviewed-by: Mark Brand --- src/sql/drivers/mysql/qsql_mysql.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sql/drivers/mysql/qsql_mysql.cpp b/src/sql/drivers/mysql/qsql_mysql.cpp index 55bf499e423..99472542bf3 100644 --- a/src/sql/drivers/mysql/qsql_mysql.cpp +++ b/src/sql/drivers/mysql/qsql_mysql.cpp @@ -1318,7 +1318,7 @@ bool QMYSQLDriver::open(const QString& db, : sslCipher.toLocal8Bit().constData()); } -#if MYSQL_VERSION_ID >= 50000 +#if MYSQL_VERSION_ID >= 50100 if (connectTimeout != 0) mysql_options(d->mysql, MYSQL_OPT_CONNECT_TIMEOUT, &connectTimeout); if (readTimeout != 0) @@ -1347,7 +1347,7 @@ bool QMYSQLDriver::open(const QString& db, setOpenError(true); return false; } -#if MYSQL_VERSION_ID >= 50000 +#if MYSQL_VERSION_ID >= 50100 if (reconnect) mysql_options(d->mysql, MYSQL_OPT_RECONNECT, &reconnect); #endif From cf88d74466cd6506875676ef2557c179d72fe422 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Tue, 6 Sep 2016 11:53:41 +0200 Subject: [PATCH 08/87] winrt: Fix file dialog handling for Windows Phone Windows Phone needs to use activation targets to properly handle the return value of a file dialog. 0f9ca217d0f479756e50459473cad7371f29047c introduced launching an app via different modes, but broke above use- case for Windows Phone. Hence, we first check if a dispatcher exists and use this one to forward the activation. Task-number: QTBUG-54342 Change-Id: If9dd2df9a45e9aa104775530c695325fe6f684f2 Reviewed-by: Oliver Wolff --- src/winmain/qtmain_winrt.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/winmain/qtmain_winrt.cpp b/src/winmain/qtmain_winrt.cpp index 83a7dc800cd..e49817ada4b 100644 --- a/src/winmain/qtmain_winrt.cpp +++ b/src/winmain/qtmain_winrt.cpp @@ -198,6 +198,14 @@ public: private: HRESULT activatedLaunch(IInspectable *activateArgs) { + // Check if an application instance is already running + // This is mostly needed for Windows Phone and file pickers + QAbstractEventDispatcher *dispatcher = QCoreApplication::eventDispatcher(); + if (dispatcher) { + QCoreApplication::postEvent(dispatcher, new QActivationEvent(activateArgs)); + return S_OK; + } + QCoreApplication *app = QCoreApplication::instance(); // Check whether the app already runs From a32217cb551612277d43b3f7c08da85abe3874ac Mon Sep 17 00:00:00 2001 From: Alberto Mardegan Date: Tue, 9 Aug 2016 17:01:37 +0300 Subject: [PATCH 09/87] QDBusServer: delay processing of D-Bus messages We must ensure that QDBusServer's newConnection() signal has been processed by the application, before starting processing messages on it. Task-number: QTBUG-55087 Change-Id: I595329b2f98788dbf9f40558b8c230c0c0817ef8 Reviewed-by: Timo Jyrinki Reviewed-by: Thiago Macieira --- src/dbus/qdbusconnection.cpp | 20 -------------------- src/dbus/qdbusconnection_p.h | 19 +++++++++++++++++++ src/dbus/qdbusintegrator.cpp | 12 ++++++++++++ src/dbus/qdbusserver.cpp | 2 ++ 4 files changed, 33 insertions(+), 20 deletions(-) diff --git a/src/dbus/qdbusconnection.cpp b/src/dbus/qdbusconnection.cpp index 7cdacc12849..c88cf898977 100644 --- a/src/dbus/qdbusconnection.cpp +++ b/src/dbus/qdbusconnection.cpp @@ -68,24 +68,6 @@ static void preventDllUnload(); Q_GLOBAL_STATIC(QDBusConnectionManager, _q_manager) -// can be replaced with a lambda in Qt 5.7 -class QDBusConnectionDispatchEnabler : public QObject -{ - Q_OBJECT - QDBusConnectionPrivate *con; -public: - QDBusConnectionDispatchEnabler(QDBusConnectionPrivate *con) : con(con) {} - -public slots: - void execute() - { - con->setDispatchEnabled(true); - if (!con->ref.deref()) - con->deleteLater(); - deleteLater(); - } -}; - struct QDBusConnectionManager::ConnectionRequestData { enum RequestType { @@ -1281,8 +1263,6 @@ QByteArray QDBusConnection::localMachineId() QT_END_NAMESPACE -#include "qdbusconnection.moc" - #ifdef Q_OS_WIN # include diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h index fff9f29b031..d16cd050588 100644 --- a/src/dbus/qdbusconnection_p.h +++ b/src/dbus/qdbusconnection_p.h @@ -375,6 +375,25 @@ extern QDBusMessage qDBusPropertySet(const QDBusConnectionPrivate::ObjectTreeNod const QDBusMessage &msg); extern QDBusMessage qDBusPropertyGetAll(const QDBusConnectionPrivate::ObjectTreeNode &node, const QDBusMessage &msg); + +// can be replaced with a lambda in Qt 5.7 +class QDBusConnectionDispatchEnabler : public QObject +{ + Q_OBJECT + QDBusConnectionPrivate *con; +public: + QDBusConnectionDispatchEnabler(QDBusConnectionPrivate *con) : con(con) {} + +public slots: + void execute() + { + con->setDispatchEnabled(true); + if (!con->ref.deref()) + con->deleteLater(); + deleteLater(); + } +}; + #endif // QT_BOOTSTRAPPED QT_END_NAMESPACE diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index 147966b9b09..878a58294c5 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -309,9 +309,21 @@ static void qDBusNewConnection(DBusServer *server, DBusConnection *connection, v // setPeer does the error handling for us QDBusErrorInternal error; newConnection->setPeer(connection, error); + newConnection->setDispatchEnabled(false); // this is a queued connection and will resume in the QDBusServer's thread emit serverConnection->newServerConnection(newConnection); + + // we've disabled dispatching of events, so now we post an event to the + // QDBusServer's thread in order to enable it after the + // QDBusServer::newConnection() signal has been received by the + // application's code + newConnection->ref.ref(); + QReadLocker serverLock(&serverConnection->lock); + QDBusConnectionDispatchEnabler *o = new QDBusConnectionDispatchEnabler(newConnection); + QTimer::singleShot(0, o, SLOT(execute())); + if (serverConnection->serverObject) + o->moveToThread(serverConnection->serverObject->thread()); } void QDBusConnectionPrivate::_q_newConnection(QDBusConnectionPrivate *newConnection) diff --git a/src/dbus/qdbusserver.cpp b/src/dbus/qdbusserver.cpp index babb270da0f..39d08b4e630 100644 --- a/src/dbus/qdbusserver.cpp +++ b/src/dbus/qdbusserver.cpp @@ -97,6 +97,7 @@ QDBusServer::QDBusServer(QObject *parent) */ QDBusServer::~QDBusServer() { + QWriteLocker locker(&d->lock); if (QDBusConnectionManager::instance()) { QMutexLocker locker(&QDBusConnectionManager::instance()->mutex); Q_FOREACH (const QString &name, d->serverConnectionNames) { @@ -104,6 +105,7 @@ QDBusServer::~QDBusServer() } d->serverConnectionNames.clear(); } + d->serverObject = nullptr; d->ref.store(0); d->deleteLater(); } From 1eb74c9f101eef530b3a5d633cc2fcd1fb547e9d Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 20 Jul 2016 11:16:32 +0200 Subject: [PATCH 10/87] QIOSTextInputOverlay: compile with Xcode 8 beta / iOS 10 The iOS 10 SDK have introduced a protocol CAAnimationDelegate, which is required for CAAnimation delegates. So we let our delegate implement it. Since the SDK is not out yet, we need to support both version 9 and 10 for now. Change-Id: I2624d8150c39439540a6554cba4921e3b9a2f0cf Reviewed-by: Jake Petroules --- src/plugins/platforms/ios/qiostextinputoverlay.mm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/plugins/platforms/ios/qiostextinputoverlay.mm b/src/plugins/platforms/ios/qiostextinputoverlay.mm index 733367f3be5..d930965bde4 100644 --- a/src/plugins/platforms/ios/qiostextinputoverlay.mm +++ b/src/plugins/platforms/ios/qiostextinputoverlay.mm @@ -299,7 +299,11 @@ static void executeBlockWithoutAnimation(Block block) // ------------------------------------------------------------------------- +#if QT_IOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__IPHONE_10_0) +@interface QIOSHandleLayer : CALayer { +#else @interface QIOSHandleLayer : CALayer { +#endif CALayer *_handleCursorLayer; CALayer *_handleKnobLayer; Qt::Edge _selectionEdge; From 66fcd0cf6674fa96ede7776ca3afa786499a07ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorbj=C3=B8rn=20Lindeijer?= Date: Tue, 6 Sep 2016 11:38:18 +0200 Subject: [PATCH 11/87] Fixed glitch when dragging a movable QTabBar tab When you would start to drag a tab, and then drag it in the other direction along the point where you started the drag, the tab would fail to follow the mouse for a distance twice the "startDragDistance", before jumping to the mouse again. Fixed this by only taking into account the "startDragDistance" when checking whether a drag is started, and to rely on the "dragInProgress" variable otherwise. Change-Id: I5dd4ebd8340fef7e870f087be68c5097b49728cb Reviewed-by: Marc Mutz --- src/widgets/widgets/qtabbar.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/widgets/widgets/qtabbar.cpp b/src/widgets/widgets/qtabbar.cpp index ed820888b49..2a163c18b5d 100644 --- a/src/widgets/widgets/qtabbar.cpp +++ b/src/widgets/widgets/qtabbar.cpp @@ -1869,9 +1869,8 @@ void QTabBar::mouseMoveEvent(QMouseEvent *event) } } - int offset = (event->pos() - d->dragStartPosition).manhattanLength(); if (event->buttons() == Qt::LeftButton - && offset > QApplication::startDragDistance() + && d->dragInProgress && d->validIndex(d->pressedIndex)) { bool vertical = verticalTabs(d->shape); int dragDistance; From 3b8df0ea44b048b8fcc4317ffdfd074e2547a95e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Szczygie=C5=82?= Date: Thu, 24 Mar 2016 23:50:24 +0100 Subject: [PATCH 12/87] QtWidgets: Send show/hide event to children on restore/minimize Child widgets should get the show/hide event when the TLW changes its state, because child widgets are also visible or invisible. This restores the Qt4 behavior (fixes the Qt4->Qt5 regression). Restoring/minimizing the TLW now sends the spontaneous show/hide event. Show events are now handled also in the expose event handler in the QWidgetWindow class, because the show event must occur before the expose event to avoid possible flicker e.g. the OpenGL content. This can happen e.g. on XCB platform. If the "WindowStateChange" event occur before the expose event (e.g. Windows platform) then the code in expose event handler will be ignored to prevent event duplications. Added autotest. Task-number: QTBUG-50589 Change-Id: Ie9a9329b1f29bff876de28d5948d0d5fb6bc1f05 Reviewed-by: Friedemann Kleint --- src/widgets/kernel/qwidget.cpp | 18 +++++-- src/widgets/kernel/qwidget_p.h | 2 + src/widgets/kernel/qwidgetwindow.cpp | 34 ++++++++++++- .../widgets/kernel/qwidget/tst_qwidget.cpp | 48 +++++++++++++++++-- 4 files changed, 92 insertions(+), 10 deletions(-) diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index b1d80d7b8fd..b99fca66207 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -276,6 +276,8 @@ QWidgetPrivate::QWidgetPrivate(int version) , renderToTextureReallyDirty(1) , renderToTextureComposeActive(0) #endif + , childrenHiddenByWState(0) + , childrenShownByExpose(0) #if defined(Q_OS_WIN) , noPaintOnScreen(0) #endif @@ -9005,13 +9007,23 @@ bool QWidget::event(QEvent *event) case QEvent::WindowStateChange: { const bool wasMinimized = static_cast(event)->oldState() & Qt::WindowMinimized; if (wasMinimized != isMinimized()) { + QWidget *widget = const_cast(this); if (wasMinimized) { - QShowEvent showEvent; - QCoreApplication::sendEvent(const_cast(this), &showEvent); + // Always send the spontaneous events here, otherwise it can break the application! + if (!d->childrenShownByExpose) { + // Show widgets only when they are not yet shown by the expose event + d->showChildren(true); + QShowEvent showEvent; + QCoreApplication::sendSpontaneousEvent(widget, &showEvent); + } + d->childrenHiddenByWState = false; // Set it always to "false" when window is restored } else { QHideEvent hideEvent; - QCoreApplication::sendEvent(const_cast(this), &hideEvent); + QCoreApplication::sendSpontaneousEvent(widget, &hideEvent); + d->hideChildren(true); + d->childrenHiddenByWState = true; } + d->childrenShownByExpose = false; // Set it always to "false" when window state changes } changeEvent(event); } diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h index b130c5421ab..5f07a8802a3 100644 --- a/src/widgets/kernel/qwidget_p.h +++ b/src/widgets/kernel/qwidget_p.h @@ -746,6 +746,8 @@ public: uint renderToTextureReallyDirty : 1; uint renderToTextureComposeActive : 1; #endif + uint childrenHiddenByWState : 1; + uint childrenShownByExpose : 1; // *************************** Platform specific ************************************ #if defined(Q_OS_WIN) diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index 872572a7e26..aa7bcc2ef8b 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -871,10 +871,40 @@ void QWidgetWindow::handleDropEvent(QDropEvent *event) void QWidgetWindow::handleExposeEvent(QExposeEvent *event) { - if (isExposed()) { + QWidgetPrivate *wPriv = m_widget->d_func(); + const bool exposed = isExposed(); + + if (wPriv->childrenHiddenByWState) { + // If widgets has been previously hidden by window state change event + // and they aren't yet shown... + if (exposed) { + // If the window becomes exposed... + if (!wPriv->childrenShownByExpose) { + // ... and they haven't been shown by this function yet - show it. + wPriv->showChildren(true); + QShowEvent showEvent; + QCoreApplication::sendSpontaneousEvent(m_widget, &showEvent); + wPriv->childrenShownByExpose = true; + } + } else { + // If the window becomes not exposed... + if (wPriv->childrenShownByExpose) { + // ... and child widgets was previously shown by the expose event - hide widgets again. + // This is a workaround, because sometimes when window is minimized programatically, + // the QPA can notify that the window is exposed after changing window state to minimized + // and then, the QPA can send next expose event with null exposed region (not exposed). + wPriv->hideChildren(true); + QHideEvent hideEvent; + QCoreApplication::sendSpontaneousEvent(m_widget, &hideEvent); + wPriv->childrenShownByExpose = false; + } + } + } + + if (exposed) { m_widget->setAttribute(Qt::WA_Mapped); if (!event->region().isNull()) - m_widget->d_func()->syncBackingStore(event->region()); + wPriv->syncBackingStore(event->region()); } else { m_widget->setAttribute(Qt::WA_Mapped, false); } diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index b7c152603cc..34a18354131 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -294,6 +294,7 @@ private slots: void showHideEvent_data(); void showHideEvent(); void showHideEventWhileMinimize(); + void showHideChildrenWhileMinimize_QTBUG50589(); void lostUpdatesOnHide(); @@ -4078,19 +4079,30 @@ class ShowHideEventWidget : public QWidget { public: int numberOfShowEvents, numberOfHideEvents; + int numberOfSpontaneousShowEvents, numberOfSpontaneousHideEvents; ShowHideEventWidget(QWidget *parent = 0) - : QWidget(parent), numberOfShowEvents(0), numberOfHideEvents(0) + : QWidget(parent) + , numberOfShowEvents(0), numberOfHideEvents(0) + , numberOfSpontaneousShowEvents(0), numberOfSpontaneousHideEvents(0) { } void create() { QWidget::create(); } - void showEvent(QShowEvent *) - { ++numberOfShowEvents; } + void showEvent(QShowEvent *e) + { + ++numberOfShowEvents; + if (e->spontaneous()) + ++numberOfSpontaneousShowEvents; + } - void hideEvent(QHideEvent *) - { ++numberOfHideEvents; } + void hideEvent(QHideEvent *e) + { + ++numberOfHideEvents; + if (e->spontaneous()) + ++numberOfSpontaneousHideEvents; + } }; void tst_QWidget::showHideEvent_data() @@ -4182,6 +4194,32 @@ void tst_QWidget::showHideEventWhileMinimize() QTRY_COMPARE(widget.numberOfShowEvents, showEventsBeforeMinimize + 1); } +void tst_QWidget::showHideChildrenWhileMinimize_QTBUG50589() +{ + const QPlatformIntegration *pi = QGuiApplicationPrivate::platformIntegration(); + if (!pi->hasCapability(QPlatformIntegration::MultipleWindows) + || !pi->hasCapability(QPlatformIntegration::NonFullScreenWindows) + || !pi->hasCapability(QPlatformIntegration::WindowManagement)) { + QSKIP("This test requires window management capabilities"); + } + + QWidget parent; + ShowHideEventWidget child(&parent); + + parent.setWindowTitle(QTest::currentTestFunction()); + parent.resize(m_testWidgetSize); + centerOnScreen(&parent); + parent.show(); + QVERIFY(QTest::qWaitForWindowExposed(&parent)); + + const int showEventsBeforeMinimize = child.numberOfSpontaneousShowEvents; + const int hideEventsBeforeMinimize = child.numberOfSpontaneousHideEvents; + parent.showMinimized(); + QTRY_COMPARE(child.numberOfSpontaneousHideEvents, hideEventsBeforeMinimize + 1); + parent.showNormal(); + QTRY_COMPARE(child.numberOfSpontaneousShowEvents, showEventsBeforeMinimize + 1); +} + void tst_QWidget::update() { #ifdef Q_OS_OSX From 3370ab9119df09ca14f7d4641c555e60c1b3f478 Mon Sep 17 00:00:00 2001 From: Milian Wolff Date: Mon, 22 Aug 2016 14:32:05 +0200 Subject: [PATCH 13/87] Never return char variants when reading prepared MySQL statements This has undesired effects when converting a QSqlRecord to JSON. A char(0) e.g. has special semantics that are undesired when reading a Tinyint column. I don't think that returning bool for the special case of a Tinyint(1) is required. This also did not happen before, and is also not happening when not using a prepared statement. Instead, a plain int/uint QVariant is returned. This patch extends tst_QSqlQuery::integralTypesMysql to also cover reading and writing booleans from/to a MySQL table column of type Tinyint(1). Additionally, the reading is now also done with a prepared statement and we also check the raw variant value. The broken behavior fixed by this patch was introduced by me in commit 194403a3483b7317cc9511bc8b2ab307775643c5. Change-Id: I028a3abd83fdd2b42d98d478950d205e5b6bbeb5 Task-number: QTBUG-53397 Reviewed-by: Andy Shaw --- src/sql/drivers/mysql/qsql_mysql.cpp | 11 ++++- .../sql/kernel/qsqlquery/tst_qsqlquery.cpp | 45 +++++++++++++------ 2 files changed, 40 insertions(+), 16 deletions(-) diff --git a/src/sql/drivers/mysql/qsql_mysql.cpp b/src/sql/drivers/mysql/qsql_mysql.cpp index 99472542bf3..c26c03ad075 100644 --- a/src/sql/drivers/mysql/qsql_mysql.cpp +++ b/src/sql/drivers/mysql/qsql_mysql.cpp @@ -596,8 +596,15 @@ QVariant QMYSQLResult::data(int field) if (f.nullIndicator) return QVariant(f.type); - if (qIsInteger(f.type)) - return QVariant(f.type, f.outField); + if (qIsInteger(f.type)) { + QVariant variant(f.type, f.outField); + // we never want to return char variants here, see QTBUG-53397 + if (static_cast(f.type) == QMetaType::UChar) + return variant.toUInt(); + else if (static_cast(f.type) == QMetaType::Char) + return variant.toInt(); + return variant; + } if (f.type != QVariant::ByteArray) val = toUnicode(d->driver->d_func()->tc, f.outField, f.bufLength); diff --git a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp index f1c4333ccdf..ba3cfb243a7 100644 --- a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp +++ b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp @@ -4007,12 +4007,14 @@ void runIntegralTypesMysqlTest(QSqlDatabase &db, const QString &tableName, const QVERIFY_SQL(q, exec("DROP TABLE IF EXISTS " + tableName)); QVERIFY_SQL(q, exec("CREATE TABLE " + tableName + " (id " + type + ")")); - const int steps = 20; - const T increment = max / steps - min / steps; + const int steps = (max == min + 1) ? 2 : 20; + const T increment = (max == min + 1) ? 1 : (max / steps - min / steps); // insert some values QVector values; + QVector variantValues; values.resize(steps); + variantValues.resize(steps); T v = min; if (withPreparedStatement) { QVERIFY_SQL(q, prepare("INSERT INTO " + tableName + " (id) VALUES (?)")); @@ -4025,17 +4027,30 @@ void runIntegralTypesMysqlTest(QSqlDatabase &db, const QString &tableName, const QVERIFY_SQL(q, exec("INSERT INTO " + tableName + " (id) VALUES (" + QString::number(v) + ")")); } values[i] = v; + variantValues[i] = QVariant::fromValue(v); v += increment; } // ensure we can read them back properly - QVERIFY_SQL(q, exec("SELECT id FROM " + tableName)); + if (withPreparedStatement) { + QVERIFY_SQL(q, prepare("SELECT id FROM " + tableName)); + QVERIFY_SQL(q, exec()); + } else { + QVERIFY_SQL(q, exec("SELECT id FROM " + tableName)); + } QVector actualValues; + QVector actualVariantValues; actualValues.reserve(values.size()); while (q.next()) { - actualValues << q.value(0).value(); + QVariant value = q.value(0); + actualVariantValues << value; + actualValues << value.value(); + QVERIFY(actualVariantValues.last().userType() != qMetaTypeId()); + QVERIFY(actualVariantValues.last().userType() != qMetaTypeId()); + QVERIFY(actualVariantValues.last().userType() != qMetaTypeId()); } QCOMPARE(actualValues, values); + QCOMPARE(actualVariantValues, variantValues); } void tst_QSqlQuery::integralTypesMysql() @@ -4046,16 +4061,18 @@ void tst_QSqlQuery::integralTypesMysql() for (int i = 0; i < 2; ++i) { const bool withPreparedStatement = (i == 1); - runIntegralTypesMysqlTest(db, "tinyIntTest", "TINYINT", withPreparedStatement); - runIntegralTypesMysqlTest(db, "unsignedTinyIntTest", "TINYINT UNSIGNED", withPreparedStatement); - runIntegralTypesMysqlTest(db, "smallIntTest", "SMALLINT", withPreparedStatement); - runIntegralTypesMysqlTest(db, "unsignedSmallIntTest", "SMALLINT UNSIGNED", withPreparedStatement); - runIntegralTypesMysqlTest(db, "mediumIntTest", "MEDIUMINT", withPreparedStatement, -(1 << 23), (1 << 23) - 1); - runIntegralTypesMysqlTest(db, "unsignedMediumIntTest", "MEDIUMINT UNSIGNED", withPreparedStatement, 0, (1 << 24) - 1); - runIntegralTypesMysqlTest(db, "intTest", "INT", withPreparedStatement); - runIntegralTypesMysqlTest(db, "unsignedIntTest", "INT UNSIGNED", withPreparedStatement); - runIntegralTypesMysqlTest(db, "bigIntTest", "BIGINT", withPreparedStatement); - runIntegralTypesMysqlTest(db, "unsignedBigIntTest", "BIGINT UNSIGNED", withPreparedStatement); + runIntegralTypesMysqlTest(db, "tinyInt1Test", "TINYINT(1)", withPreparedStatement); + runIntegralTypesMysqlTest(db, "unsignedTinyInt1Test", "TINYINT(1) UNSIGNED", withPreparedStatement); + runIntegralTypesMysqlTest(db, "tinyIntTest", "TINYINT", withPreparedStatement); + runIntegralTypesMysqlTest(db, "unsignedTinyIntTest", "TINYINT UNSIGNED", withPreparedStatement); + runIntegralTypesMysqlTest(db, "smallIntTest", "SMALLINT", withPreparedStatement); + runIntegralTypesMysqlTest(db, "unsignedSmallIntTest", "SMALLINT UNSIGNED", withPreparedStatement); + runIntegralTypesMysqlTest(db, "mediumIntTest", "MEDIUMINT", withPreparedStatement, -(1 << 23), (1 << 23) - 1); + runIntegralTypesMysqlTest(db, "unsignedMediumIntTest", "MEDIUMINT UNSIGNED", withPreparedStatement, 0, (1 << 24) - 1); + runIntegralTypesMysqlTest(db, "intTest", "INT", withPreparedStatement); + runIntegralTypesMysqlTest(db, "unsignedIntTest", "INT UNSIGNED", withPreparedStatement); + runIntegralTypesMysqlTest(db, "bigIntTest", "BIGINT", withPreparedStatement); + runIntegralTypesMysqlTest(db, "unsignedBigIntTest", "BIGINT UNSIGNED", withPreparedStatement); } } From 7a593c8c98462380b3bd77053bd0a4a35c2b31f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tony=20Saraj=C3=A4rvi?= Date: Thu, 18 Aug 2016 15:46:16 +0300 Subject: [PATCH 14/87] Blacklist selftest runSubTest This one selftest is currently blocking OS X 10.11 from entering the CI. It can't be reproduced when run manually. Task-number: QTBUG-55155 Change-Id: I4553ef2d7813b29f5dc8577976c4482686346504 Reviewed-by: Timur Pocheptsov --- tests/auto/testlib/selftests/test/BLACKLIST | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 tests/auto/testlib/selftests/test/BLACKLIST diff --git a/tests/auto/testlib/selftests/test/BLACKLIST b/tests/auto/testlib/selftests/test/BLACKLIST new file mode 100644 index 00000000000..2d4adf1feb2 --- /dev/null +++ b/tests/auto/testlib/selftests/test/BLACKLIST @@ -0,0 +1,3 @@ +#QTBUG-55155 +[runSubTest:maxwarnings all loggers] +osx-10.11 From 7529c39ba350c3fe9a2b4a96d3300481e3ea419f Mon Sep 17 00:00:00 2001 From: Dyami Caliri Date: Wed, 7 Sep 2016 11:05:51 -0700 Subject: [PATCH 15/87] QStyleOption: return Q_NULLPTR from qstyleoption_cast instead of 0 qstyleoption_cast should use Q_NULLPTR to represent a null pointer. Task-number: QTBUG-45291 Change-Id: I85078ceb435b310daf63db2ed771be2f36cf3e4f Reviewed-by: Marc Mutz --- src/widgets/styles/qstyleoption.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/widgets/styles/qstyleoption.h b/src/widgets/styles/qstyleoption.h index 9fd693d033e..74dd35cc4ae 100644 --- a/src/widgets/styles/qstyleoption.h +++ b/src/widgets/styles/qstyleoption.h @@ -664,7 +664,7 @@ T qstyleoption_cast(const QStyleOption *opt) || (int(Opt::Type) == QStyleOption::SO_Complex && opt->type > QStyleOption::SO_Complex))) return static_cast(opt); - return 0; + return Q_NULLPTR; } template @@ -676,7 +676,7 @@ T qstyleoption_cast(QStyleOption *opt) || (int(Opt::Type) == QStyleOption::SO_Complex && opt->type > QStyleOption::SO_Complex))) return static_cast(opt); - return 0; + return Q_NULLPTR; } // -------------------------- QStyleHintReturn ------------------------------- @@ -725,7 +725,7 @@ T qstyleoption_cast(const QStyleHintReturn *hint) if (hint && hint->version <= Opt::Version && (hint->type == Opt::Type || int(Opt::Type) == QStyleHintReturn::SH_Default)) return static_cast(hint); - return 0; + return Q_NULLPTR; } template @@ -735,7 +735,7 @@ T qstyleoption_cast(QStyleHintReturn *hint) if (hint && hint->version <= Opt::Version && (hint->type == Opt::Type || int(Opt::Type) == QStyleHintReturn::SH_Default)) return static_cast(hint); - return 0; + return Q_NULLPTR; } #if !defined(QT_NO_DEBUG_STREAM) From ce9147f917ee906efdabed355b93a934b2aefa9a Mon Sep 17 00:00:00 2001 From: Jani Heikkinen Date: Wed, 7 Sep 2016 18:28:04 +0300 Subject: [PATCH 16/87] Add changes file for 5.6.2 Change-Id: Ie1d6d7f3adf61b482b8e797849dbb2b3053fe720 Reviewed-by: Kai Koehne Reviewed-by: Frederik Gladhorn --- dist/changes-5.6.2 | 343 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 343 insertions(+) create mode 100644 dist/changes-5.6.2 diff --git a/dist/changes-5.6.2 b/dist/changes-5.6.2 new file mode 100644 index 00000000000..5a004e98f87 --- /dev/null +++ b/dist/changes-5.6.2 @@ -0,0 +1,343 @@ +Qt 5.6.2 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.6.0. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + + http://doc.qt.io/qt-5/index.html + +The Qt version 5.6 series is binary compatible with the 5.5.x series. +Applications compiled for 5.5 will continue to run with 5.6. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + + https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +****************************************************************************** +* Important Behavior Changes * +****************************************************************************** + + - [QTBUG-45031] The NSURLConnection backend of QNetworkAccessManager has + been removed, since SecureTransport is the default SSL backend on iOS + and is enabled by default. This means that building with -no-openssl + -no-securetransport will no longer provide SSL capabilities on iOS. + + - QUrl::resolved() no longer treats a URL with a scheme as a relative URL + if it matches this URL's scheme. For now it still treats "file:name.txt" + as relative for compatibility, but be warned that in Qt 5.8 it will no + longer consider those to be relative. Both isRelative() and RFC 3986 say + that such URLs are not relative, so starting from Qt 5.8, resolved() will + return them as is. + + - [QTBUG-47815] QDateTime now uses QLocale to get the "AM" and "PM" strings + when parsing times, instead of strings obtained from the loaded + translations. + +****************************************************************************** +* Library * +****************************************************************************** + +QtCore +------ + + - Optimized toLatin1()/toUtf8() called on a QStringBuilder expression. + - [QTBUG-18729][QTBUG-32457] Fixed a bug that caused Windows to show + dialogs prompting the user to insert media when certain operations were + made with Qt I/O classes, particularly QStorageInfo::mountedVolumes(). + + - QCommandLineParser: + * The methods that exit() the application will now call cleanup routines + registered with qAddPostRoutine. + + - QDataStream: + * Fixed compatibility of QTime serialization with Qt 3. + + - QDebug: + * Fixed streaming of QChars. + + - QJsonObject: + * Optimized equality operator. + + - QJsonValue: + * Fixed use-after-free in assignment operator. + + - QLockFile: + * Fixed permissions on lock files on Unix to allow for adjustments via + umask. + * [QTBUG-53392] Improved the robustness of detecting stale lock files on + Windows. + + - QMutex: + * [QTBUG-54831] Fixed a bug that caused some applications to crash on + exit, depending on the order of creation of certain statics inside Qt. + + - QObject: + * Fixed a crash when connecting a signal to a lambda or functor while + using Qt::UniqueConnection (note: the connection is still not unique). + + - QStringListModel: + * Fixed dataChanged()'s 'roles' parameter to always contain both + Qt::EditRole and Qt::DisplayRole. + + - QTemporaryFile: + * [QTBUG-54810] Fixed a bug that caused QTemporaryFile to fail when the + file name contained non-ASCII characters, on Windows. + + - QTimeZone: + * [QTBUG-53071] Fixed a bug that caused QTimeZone to mis-parse time zones + whose names were not simple letter and digit combinations. + + - QUrl: + * Made QUrl stricter in what it accepts for schemes, to comply with the + relevant standards. QUrl will no longer accept schemes starting with a + plus (+), a dash (-) or a dot (.). + + - QVariant: + * [QTBUG-53384] Fixed QVariant::canConvert and conversion from integer + types to enumeration types. + * [QTBUG-54893] Fixed a bug that caused QVariants not to compare properly + if they contained QStringLists. + + - QVector: + * [QTBUG-51758] Fixed a bug that would cause QVector to crash if one + called reserve(0). + + - QXmlStreamReader: + * Fixed a bug in the XML parser that prevented to load XML that + contained invalid characters for XML 1.0. + + - QXmlStreamWriter: + * Fixed a bug that prevented the generation of valid XML files when + using encoding with 8 bit per character but not ASCII compatible. + QXMLStreamWriter generated XML markup using always ASCII in this case. + +QtGui +----- + + - Fixed UBSan errors in + * QColor + * QGrayRaster + * QRasterizer + + - Removed a total of 1610 relocations from the library. + + - QGuiApplication: + * [QTBUG-51703] Fixed a bug that would cause QGuiApplication::sync() to + be left undefined for Qt builds without session management support. + + - QIconLoaderEngine: + * Fixed theme lookup for scalable entries. + + - Text: + * [QTBUG-42033] Fixed bug where a QTextLayout with + ShowLineAndParagraphSeparators would modify the layout's input string. + * [QTBUG-49452] Fixed a performance regression in Freetype engine that + was introduced in Qt 5.5. + * [QTBUG-54180] Fixed performance regression when rapidly switching + between a large set of fonts. + + - Windows: + * [QTBUG-54494] Fixed stretch when combined with either no or vertical + hinting preference or a device pixel ratio different from 1. + * [QTBUG-51024] Fixed height of text bounding box when using no or + vertical hinting preference, or when the device pixel ratio is + different from 1. + +QtNetwork +--------- + + - QAuthenticator: + * [QTBUG-53338] Fixed crash when comparing an initialized QAuthenticator + with an uninitialized QAuthenticator. + +QtSql +----- + + - [QTBUG-53969][QTBUG-53237] Fixed QSqlQuery::prepare value truncation + error when using UNSIGNED values in a MySQL database. + +QtWidgets +--------- + + - Fixed UBSan/Coverity errors in: + * QAbstractItemView + * QDataWidgetMapper + * QTreeWidget + * QWidgetLineControl + + - Removed a total of 167 relocations from the library. + + - QAbstractItemDelegate: + * [QTBUG-16469] Show localized detailed tooltips and "What's this?" + texts. + +- QAbstractItemView: + * [QTBUG-53541] Fixed a bug involving drawing the drop indicator + where it shouldn't be drawn. + * Fixed a bug in setSelectionModel() which could lead to model indexes + from a different model be reused on a new model. + + - QAbstractSpinBox: + * [QTBUG-55249] Fixed a bug related to first key press. + + - QColorDialog: + * Fixed ignored alpha channel in getRgb(). + + - QComboBox: + * [QTBUG-54191] Fixed a crash on setEditable(false) called from + editTextChanged(). + + - QCompleter: + * [QTBUG-54642] Fixed wrong completion role after a QFileSystemModel + has been used. + + - QDesktopWidget: + * [QTBUG-52101] Fixed tracking of QScreens. + * [QTBUG-52606] Fixed a bug related to DPI-scaling in screenNumber(). + + - QDialog: + * [QTBUG-52735] Fixed a bug involving moves between screens with + different DPI-scaling factors. + + - QDockWidget: + * [QTBUG-52107][QTBUG-53754] Fixed bugs related to floating group tab + window title. + * [QTBUG-52108] A QDockWidgetGroupWindow can now be dragged into one of + its QDockWidgets. + * [QTBUG-53808] Fixed a bug that caused an undocked dock widget to lose + its decoration. + * [QTBUG-54185] Unbroke drag-and-drop. + + - QGraphicsProxyWidget: + * [QTBUG-55112] Fixed a bug that caused the widget to receive events + during construction. + + - QLineEdit: + * [QTBUG-49374] Fixed icons being too small on a High DPI screen + without scaling. + * [QTBUG-52796] Fixed QKeySequence::MoveToStartOfLine shortcut + being ignored. + * [QTBUG-54425] Fixed missing clear button on macOS. + + - QMainWindow: + * [QTBUG-50491] Fixed a bug related to restoring dock widgets with + GroupedDragging. + * [QTBUG-52108] Fixed a bug related to context menus in the presence of + floating tabs. + + - QMenu: + * [QTBUG-53054] Submenus can now be opened on left mouse button + press, too. + + - QMenuBar: + * [QTBUG-53205] Fixed bugs (incl. crashes) involving reparented + menu bars. + + - QOpenGLWidget: + * [QTBUG-50818][QTBUG-51815][QTBUG-54241][QTBUG-52419] Fixed several + repainting bugs and other drawing artifacts. + + - QSideBar: + * Fixed a nullptr dereference on platforms that do not support + QFileSystemWatcher. + + - QSystemTrayIcon: + * [QTBUG-53591] Use large icon for balloon message on Windows systems. + + - QTabBar: + * Fixed a performance problem involving font metrics. + + - QTreeView: + * [QTBUG-52793] Fixed a key navigation bug when the columns were + reordered. + +- QTreeWidget: + * [QTBUG-50207] Now handles device pixel ratio in animations correctly. + +- QWidget: + * [QTBUG-39887] Restored documented behavior for the + WA_X11NetWmWindowType* attributes. + * [QTBUG-41135][QTBUG-50030][QTBUG-50136][QTBUG-52507] Fixed + mapTo/FromGlobal() in case of widget hierarchies embedded into + QGraphicsView with transformations. + * [QTBUG-45484] Fixed setWindowRole(). + * [QTBUG-50796] Reduced paint-events when resizing native widgets. + * [QTBUG-52123] Fixed a bug by which opaque texture-based widgets + were not always shown. + * [QTBUG-53515] Added a workaround for render-to-texture widgets in + fullscreen windows. + * [QTBUG-54734] Worked around an issue with translucent GL windows + on Windows. + * [QTBUG-54906] Fixed a bug relaed to fullscreen handling on Windows. + + - Styles: + * Fixed several cases of QStyleOptions being created with null + version. + * [QTBUG-51266] Fixed painting of small progress bars on Vista+. + * [QTBUG-54630] Fixed a crash in QMacStyle::styleHint(). + * [QTBUG-49374] The Windows style now takes the monitor's differing + logical DPI into account when calculating native metrics. + +****************************************************************************** +* Platform-specific Changes * +****************************************************************************** + +Android +------- + + - [QTBUG-50724] Added support for clang compiler. + - [QTBUG-53511] Fixed CJK font resolution on Android 7. + +BSDs +---- + + - The freebsd-g++ mkspec was moved back and no longer requires the + "unsupported/" prefix, matching the FreeBSD ports tree, as FreeBSD 9.3 + still defaults to using GCC. Users of GCC that did not previously use + the ports patch will need to adapt their build scripts and drop the + "unsupported/" prefix. + - Fixed a number of compilation issues on FreeBSD, NetBSD and OpenBSD. Qt + should now build out-of-the-box (no patches needed) on those systems. + +Linux +----- + + - [QTBUG-54733] It is now possible to opt out from installing signal + handlers when running with eglfs and linuxfb by setting the + QT_QPA_NO_SIGNAL_HANDLER environment variable to a non-zero value. + +macOS +----- + + - [QTBUG-48953] Pasting text from Qt applications to Apple Mail now works. + - [QTBUG-48953] “text/vcard” is now required as the mime type when + placing vCards on the clipboard. + - OS X => macOS rename in Q_OS_ macros/docs, qmake scopes, + file selectors, etc. + - Add new QSysInfo values and MAC_OS_X / __MAC_ / __IPHONE_ values for + macOS 10.12 and iOS 9.1 through 10.0. + - Update prettyProductName with new macOS "Sierra" codename. + +Windows +------- + + - Fixed a new[]/delete mismatch in Windows tablet support. + +X11 / XCB +--------- + + - Fixed the value of the 'defined' field in ATSPI GetAttributeValue + results. + +**************************************************************************** +* Tools * +**************************************************************************** + +moc +--- + - [QTBUG-53441] Fixed crash on file ending with a backslash followed by + carriage return From 1f01423e86a4ad6f94db06168272d4cf3d47d44b Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 14 Sep 2016 13:34:56 -0700 Subject: [PATCH 17/87] Move the ATSPI Linux A11y change to the Linux block I actually doubt it's Linux-specific (more like all Unix), but the changes are in files called "linuxaccessibility". Change-Id: I9093948278414644a416fffd14744ae826b83303 Reviewed-by: Marc Mutz --- dist/changes-5.6.2 | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/dist/changes-5.6.2 b/dist/changes-5.6.2 index 5a004e98f87..7b62a018f31 100644 --- a/dist/changes-5.6.2 +++ b/dist/changes-5.6.2 @@ -309,6 +309,8 @@ Linux - [QTBUG-54733] It is now possible to opt out from installing signal handlers when running with eglfs and linuxfb by setting the QT_QPA_NO_SIGNAL_HANDLER environment variable to a non-zero value. + - Fixed the value of the 'defined' field in ATSPI GetAttributeValue + results. macOS ----- @@ -327,12 +329,6 @@ Windows - Fixed a new[]/delete mismatch in Windows tablet support. -X11 / XCB ---------- - - - Fixed the value of the 'defined' field in ATSPI GetAttributeValue - results. - **************************************************************************** * Tools * **************************************************************************** From a54d44298f6d2ecc1ec4d8c5c42c89c8a06fc5dd Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Wed, 14 Sep 2016 16:14:16 +0200 Subject: [PATCH 18/87] QLatin1String: Fix UB (nullptr passed) in relational operators Found by UBSan: qstring.h:1160:44: runtime error: null pointer passed as argument 1, which is declared to never be null qstring.h:1160:44: runtime error: null pointer passed as argument 2, which is declared to never be null Fix by avoiding the memcmp() calls if there's a chance that they might be called with nullptr. While at it, also implement !=, >, <=, >= in terms of ==, <, and add a test, because this particular UB was not fingered by any of the QtCore test cases, but by a Qt3D one. Change-Id: I413792dcc8431ef14f0c79f26e89a3e9fab69465 Reviewed-by: Thiago Macieira Reviewed-by: Edward Welbourne --- src/corelib/tools/qstring.h | 22 +++---- .../tools/qlatin1string/tst_qlatin1string.cpp | 57 +++++++++++++++++++ 2 files changed, 68 insertions(+), 11 deletions(-) diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h index 886973fe10a..58ad2caa2b4 100644 --- a/src/corelib/tools/qstring.h +++ b/src/corelib/tools/qstring.h @@ -1127,21 +1127,21 @@ inline bool operator!=(QString::Null, const QString &s) { return !s.isNull(); } inline bool operator!=(const QString &s, QString::Null) { return !s.isNull(); } inline bool operator==(QLatin1String s1, QLatin1String s2) Q_DECL_NOTHROW -{ return (s1.size() == s2.size() && !memcmp(s1.latin1(), s2.latin1(), s1.size())); } +{ return s1.size() == s2.size() && (!s1.size() || !memcmp(s1.latin1(), s2.latin1(), s1.size())); } inline bool operator!=(QLatin1String s1, QLatin1String s2) Q_DECL_NOTHROW -{ return (s1.size() != s2.size() || memcmp(s1.latin1(), s2.latin1(), s1.size())); } +{ return !operator==(s1, s2); } inline bool operator<(QLatin1String s1, QLatin1String s2) Q_DECL_NOTHROW -{ int r = memcmp(s1.latin1(), s2.latin1(), qMin(s1.size(), s2.size())); - return (r < 0) || (r == 0 && s1.size() < s2.size()); } -inline bool operator<=(QLatin1String s1, QLatin1String s2) Q_DECL_NOTHROW -{ int r = memcmp(s1.latin1(), s2.latin1(), qMin(s1.size(), s2.size())); - return (r < 0) || (r == 0 && s1.size() <= s2.size()); } +{ + const int len = qMin(s1.size(), s2.size()); + const int r = len ? memcmp(s1.latin1(), s2.latin1(), len) : 0; + return r < 0 || (r == 0 && s1.size() < s2.size()); +} inline bool operator>(QLatin1String s1, QLatin1String s2) Q_DECL_NOTHROW -{ int r = memcmp(s1.latin1(), s2.latin1(), qMin(s1.size(), s2.size())); - return (r > 0) || (r == 0 && s1.size() > s2.size()); } +{ return operator<(s2, s1); } +inline bool operator<=(QLatin1String s1, QLatin1String s2) Q_DECL_NOTHROW +{ return !operator>(s1, s2); } inline bool operator>=(QLatin1String s1, QLatin1String s2) Q_DECL_NOTHROW -{ int r = memcmp(s1.latin1(), s2.latin1(), qMin(s1.size(), s2.size())); - return (r > 0) || (r == 0 && s1.size() >= s2.size()); } +{ return !operator<(s1, s2); } inline bool QLatin1String::operator==(const QString &s) const Q_DECL_NOTHROW { return s == *this; } diff --git a/tests/auto/corelib/tools/qlatin1string/tst_qlatin1string.cpp b/tests/auto/corelib/tools/qlatin1string/tst_qlatin1string.cpp index 290c9fc12a4..6f16120bd0f 100644 --- a/tests/auto/corelib/tools/qlatin1string/tst_qlatin1string.cpp +++ b/tests/auto/corelib/tools/qlatin1string/tst_qlatin1string.cpp @@ -35,6 +35,15 @@ #include +// Preserve QLatin1String-ness (QVariant(QLatin1String) creates a QVariant::String): +struct QLatin1StringContainer { + QLatin1String l1; +}; +QT_BEGIN_NAMESPACE +Q_DECLARE_TYPEINFO(QLatin1StringContainer, Q_MOVABLE_TYPE); +QT_END_NAMESPACE +Q_DECLARE_METATYPE(QLatin1StringContainer) + class tst_QLatin1String : public QObject { Q_OBJECT @@ -42,6 +51,8 @@ class tst_QLatin1String : public QObject private Q_SLOTS: void nullString(); void emptyString(); + void relationalOperators_data(); + void relationalOperators(); }; void tst_QLatin1String::nullString() @@ -119,7 +130,53 @@ void tst_QLatin1String::emptyString() } } +void tst_QLatin1String::relationalOperators_data() +{ + QTest::addColumn("lhs"); + QTest::addColumn("lhsOrderNumber"); + QTest::addColumn("rhs"); + QTest::addColumn("rhsOrderNumber"); + struct Data { + QLatin1String l1; + int order; + } data[] = { + { QLatin1String(), 0 }, + { QLatin1String(""), 0 }, + { QLatin1String("a"), 1 }, + { QLatin1String("aa"), 2 }, + { QLatin1String("b"), 3 }, + }; + + for (Data *lhs = data; lhs != data + sizeof data / sizeof *data; ++lhs) { + for (Data *rhs = data; rhs != data + sizeof data / sizeof *data; ++rhs) { + QLatin1StringContainer l = { lhs->l1 }, r = { rhs->l1 }; + QTest::newRow(qPrintable(QString::asprintf("\"%s\" <> \"%s\"", + lhs->l1.data() ? lhs->l1.data() : "nullptr", + rhs->l1.data() ? rhs->l1.data() : "nullptr"))) + << l << lhs->order << r << rhs->order; + } + } +} + +void tst_QLatin1String::relationalOperators() +{ + QFETCH(QLatin1StringContainer, lhs); + QFETCH(int, lhsOrderNumber); + QFETCH(QLatin1StringContainer, rhs); + QFETCH(int, rhsOrderNumber); + +#define CHECK(op) \ + QCOMPARE(lhs.l1 op rhs.l1, lhsOrderNumber op rhsOrderNumber) \ + /*end*/ + CHECK(==); + CHECK(!=); + CHECK(< ); + CHECK(> ); + CHECK(<=); + CHECK(>=); +#undef CHECK +} QTEST_APPLESS_MAIN(tst_QLatin1String) From 258e4d05edcb36406c32be56a8207fe992d284dc Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 15 Sep 2016 00:36:54 +0200 Subject: [PATCH 19/87] QDBusError: don't bother dealing with unusable 'unused' field The move constructor as well as member-swap were dealing with the 'unused' field as if it would be usable. But as the comment in the default ctor suggests, the field can never be used in Qt 5, due to the inline dtor. So, don't bother with the field. Doing so only triggers checkers such as Coverity. Also mark the field for removal in Qt 6. Coverity-Id: 154503 Coverity-Id: 154510 Change-Id: If42c5ed66d1133e651de7477f3313b3989b64bc9 Reviewed-by: Thiago Macieira --- src/dbus/qdbuserror.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/dbus/qdbuserror.h b/src/dbus/qdbuserror.h index ce5275dee9e..12a19a8edaf 100644 --- a/src/dbus/qdbuserror.h +++ b/src/dbus/qdbuserror.h @@ -94,8 +94,8 @@ public: QDBusError(const QDBusError &other); #ifdef Q_COMPILER_RVALUE_REFS QDBusError(QDBusError &&other) Q_DECL_NOTHROW - : code(other.code), msg(std::move(other.msg)), nm(std::move(other.nm)), unused(other.unused) - { other.unused = Q_NULLPTR; } + : code(other.code), msg(std::move(other.msg)), nm(std::move(other.nm)) + {} QDBusError &operator=(QDBusError &&other) Q_DECL_NOTHROW { swap(other); return *this; } #endif QDBusError &operator=(const QDBusError &other); @@ -108,7 +108,6 @@ public: qSwap(code, other.code); qSwap(msg, other.msg); qSwap(nm, other.nm); - qSwap(unused, other.unused); } ErrorType type() const; @@ -122,6 +121,8 @@ private: ErrorType code; QString msg; QString nm; + // ### This class has an implicit (therefore inline) destructor + // so the following field cannot be used: void *unused; }; Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QDBusError) From 2cf3dee10be1d2163eff0893f51f9ece643c2540 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Szczygie=C5=82?= Date: Mon, 12 Sep 2016 15:22:20 +0200 Subject: [PATCH 20/87] xcb: Don't send "Qt::WindowNoState" event when hiding minimized window This prevents getting "QWidget::showEvent()" when hiding minimized widget on some WMs like Marco or Xfwm4. If QWindow is minimized and it gets the new "XCB_WM_STATE_WITHDRAWN" event from XCB, then don't change the QWindow state. Task-number: QTBUG-55942 Change-Id: I90cfc2bf55e507864ad8f26c8f569ea562c27314 Reviewed-by: Uli Schlachter Reviewed-by: Shawn Rutledge --- src/plugins/platforms/xcb/qxcbwindow.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index da5020168f4..d46228cf8ac 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -2543,8 +2543,13 @@ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *ev if (reply && reply->format == 32 && reply->type == atom(QXcbAtom::WM_STATE)) { const quint32 *data = (const quint32 *)xcb_get_property_value(reply); - if (reply->length != 0 && XCB_WM_STATE_ICONIC == data[0]) - newState = Qt::WindowMinimized; + if (reply->length != 0) { + if (data[0] == XCB_WM_STATE_ICONIC + || (data[0] == XCB_WM_STATE_WITHDRAWN + && m_lastWindowStateEvent == Qt::WindowMinimized)) { + newState = Qt::WindowMinimized; + } + } } free(reply); } else { // _NET_WM_STATE can't change minimized state From 25c9a6c9b46e6ae58dcccdc3ba158d14945cbf33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Szczygie=C5=82?= Date: Wed, 4 May 2016 00:23:16 +0200 Subject: [PATCH 21/87] QtWidgets: Fix enter/leave events on popup menus If the sloppy menu popups - send the leave event to the last active menu (except Cocoa), because only currect active menu gets enter/leave events (currently Cocoa is an exception). Check that the menu really has a mouse before hiding the sloppy menu - don't rely on enter events. This patch removes some unnecessary synthetic mouse enter/leave events from QMenu which causes event duplications with different mouse cursor position. Refactor sloppy menu timer handling - start or restart timers on mouse move events. Enter/leave events are not reliable. Fixes: - better enter/leave events handling for native widget actions, - reduce duplicated enter/leave events for menu actions, - better handle torn off sloppy menus. Partially reverts: 0ed68f3f58c63bd1496cb268bd83881da180051f Amends: 57ecd5aeeb1f609206933be66b92fcdf703703d7 Task-number: QTBUG-53068 Change-Id: I7ad56ac1619db124915d373fab82d0512d44c90e Reviewed-by: Shawn Rutledge --- src/widgets/kernel/qwidgetwindow.cpp | 34 ++++---- src/widgets/widgets/qmenu.cpp | 86 +++++++++++-------- src/widgets/widgets/qmenu_p.h | 23 +---- .../widgets/kernel/qwidget/tst_qwidget.cpp | 5 +- 4 files changed, 74 insertions(+), 74 deletions(-) diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index aa7bcc2ef8b..95f63025fb9 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -381,7 +381,14 @@ void QWidgetWindow::handleEnterLeaveEvent(QEvent *event) const QEnterEvent *ee = static_cast(event); QWidget *child = m_widget->childAt(ee->pos()); QWidget *receiver = child ? child : m_widget.data(); - QApplicationPrivate::dispatchEnterLeave(receiver, 0, ee->screenPos()); + QWidget *leave = Q_NULLPTR; + if (QApplicationPrivate::inPopupMode() && receiver == m_widget + && qt_last_mouse_receiver != m_widget) { + // This allows to deliver the leave event to the native widget + // action on first-level menu. + leave = qt_last_mouse_receiver; + } + QApplicationPrivate::dispatchEnterLeave(receiver, leave, ee->screenPos()); qt_last_mouse_receiver = receiver; } } @@ -471,34 +478,31 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event) receiver = popupChild; if (receiver != activePopupWidget) widgetPos = receiver->mapFromGlobal(event->globalPos()); - QWidget *alien = receiver; #if !defined(Q_OS_OSX) && !defined(Q_OS_IOS) // Cocoa tracks popups const bool reallyUnderMouse = activePopupWidget->rect().contains(mapped); const bool underMouse = activePopupWidget->underMouse(); - if (activePopupWidget != m_widget || (!underMouse && qt_button_down)) { - // If active popup menu is not the first-level popup menu then we must emulate enter/leave events, - // because first-level popup menu grabs the mouse and enter/leave events are delivered only to it - // by QPA. Make an exception for first-level popup menu when the mouse button is pressed on widget. - if (underMouse != reallyUnderMouse) { - if (reallyUnderMouse) { + if (underMouse != reallyUnderMouse) { + if (reallyUnderMouse) { + const QPoint receiverMapped = receiver->mapFromGlobal(event->screenPos().toPoint()); + // Prevent negative mouse position on enter event - this event + // should be properly handled in "handleEnterLeaveEvent()". + if (receiverMapped.x() >= 0 && receiverMapped.y() >= 0) { QApplicationPrivate::dispatchEnterLeave(receiver, Q_NULLPTR, event->screenPos()); qt_last_mouse_receiver = receiver; - } else { - QApplicationPrivate::dispatchEnterLeave(Q_NULLPTR, qt_last_mouse_receiver, event->screenPos()); - qt_last_mouse_receiver = receiver; - receiver = activePopupWidget; } + } else { + QApplicationPrivate::dispatchEnterLeave(Q_NULLPTR, qt_last_mouse_receiver, event->screenPos()); + qt_last_mouse_receiver = receiver; + receiver = activePopupWidget; } - } else if (!reallyUnderMouse) { - alien = Q_NULLPTR; } #endif QMouseEvent e(event->type(), widgetPos, event->windowPos(), event->screenPos(), event->button(), event->buttons(), event->modifiers(), event->source()); e.setTimestamp(event->timestamp()); - QApplicationPrivate::sendMouseEvent(receiver, &e, alien, receiver->window(), &qt_button_down, qt_last_mouse_receiver); + QApplicationPrivate::sendMouseEvent(receiver, &e, receiver, receiver->window(), &qt_button_down, qt_last_mouse_receiver); qt_last_mouse_receiver = receiver; } else { // close disabled popups when a mouse button is pressed or released diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp index c194547f2d0..2fd5340f3b7 100644 --- a/src/widgets/widgets/qmenu.cpp +++ b/src/widgets/widgets/qmenu.cpp @@ -70,22 +70,6 @@ QT_BEGIN_NAMESPACE QMenu *QMenuPrivate::mouseDown = 0; -QPointer QMenuPrivate::previousMouseMenu(Q_NULLPTR); -static void handleEnterLeaveEvents(QPointer *previous_ptr, QMenu *next) -{ - QWidget *previous = previous_ptr->data(); - if (previous != next) { - if (previous) { - QEvent leaveEvent(QEvent::Leave); - QApplication::sendEvent(previous, &leaveEvent); - } - if (next) { - QEvent enterEvent(QEvent::Enter); - QApplication::sendEvent(next, &enterEvent); - } - } - *previous_ptr = next; -} /* QMenu code */ // internal class used for the torn off popup @@ -504,8 +488,6 @@ void QMenuPrivate::hideMenu(QMenu *menu) menu->d_func()->causedPopup.action = 0; menu->close(); menu->d_func()->causedPopup.widget = 0; - if (previousMouseMenu.data() == menu) - handleEnterLeaveEvents(&previousMouseMenu, Q_NULLPTR); } void QMenuPrivate::popupAction(QAction *action, int delay, bool activateFirst) @@ -671,10 +653,26 @@ void QMenuSloppyState::enter() m_parent->childEnter(); } +void QMenuSloppyState::childEnter() +{ + stopTimer(); + if (m_parent) + m_parent->childEnter(); +} + +void QMenuSloppyState::leave() +{ + if (!m_dont_start_time_on_leave) { + if (m_parent) + m_parent->childLeave(); + startTimerIfNotRunning(); + } +} + void QMenuSloppyState::childLeave() { if (m_enabled && !QMenuPrivate::get(m_menu)->hasReceievedEnter) { - startTimer(); + startTimerIfNotRunning(); if (m_parent) m_parent->childLeave(); } @@ -720,8 +718,17 @@ public: void QMenuSloppyState::timeout() { QMenuPrivate *menu_priv = QMenuPrivate::get(m_menu); + + bool reallyHasMouse = menu_priv->hasReceievedEnter; + if (!reallyHasMouse) { + // Check whether the menu really has a mouse, because only active popup + // menu gets the enter/leave events. Currently Cocoa is an exception. + const QPoint lastCursorPos = QGuiApplicationPrivate::lastCursorPosition.toPoint(); + reallyHasMouse = m_menu->frameGeometry().contains(lastCursorPos); + } + if (menu_priv->currentAction == m_reset_action - && menu_priv->hasReceievedEnter + && reallyHasMouse && (menu_priv->currentAction && menu_priv->currentAction->menu() == menu_priv->activeMenu)) { return; @@ -729,13 +736,13 @@ void QMenuSloppyState::timeout() ResetOnDestroy resetState(this, &m_init_guard); - if (hasParentActiveDelayTimer() || !m_menu || !m_menu->isVisible()) + if (hasParentActiveDelayTimer() || !m_menu->isVisible()) return; if (m_sub_menu) menu_priv->hideMenu(m_sub_menu); - if (menu_priv->hasReceievedEnter) + if (reallyHasMouse) menu_priv->setCurrentAction(m_reset_action,0); else menu_priv->setCurrentAction(Q_NULLPTR, 0); @@ -1089,10 +1096,8 @@ bool QMenuPrivate::mouseEventTaken(QMouseEvent *e) tearoffHighlighted = 0; } - if (q->frameGeometry().contains(e->globalPos())) { //otherwise if the event is in our rect we want it.. - handleEnterLeaveEvents(&previousMouseMenu, q); - return false; - } + if (q->frameGeometry().contains(e->globalPos())) + return false; //otherwise if the event is in our rect we want it.. for(QWidget *caused = causedPopup.widget; caused;) { bool passOnEvent = false; @@ -1108,17 +1113,16 @@ bool QMenuPrivate::mouseEventTaken(QMouseEvent *e) next_widget = m->d_func()->causedPopup.widget; } if (passOnEvent) { - handleEnterLeaveEvents(&previousMouseMenu,qobject_cast(caused)); - if(e->type() != QEvent::MouseButtonRelease || mouseDown == caused) { - QMouseEvent new_e(e->type(), cpos, caused->mapTo(caused->topLevelWidget(), cpos), e->screenPos(), - e->button(), e->buttons(), e->modifiers(), e->source()); - QApplication::sendEvent(caused, &new_e); - return true; + if (e->type() != QEvent::MouseButtonRelease || mouseDown == caused) { + QMouseEvent new_e(e->type(), cpos, caused->mapTo(caused->topLevelWidget(), cpos), e->screenPos(), + e->button(), e->buttons(), e->modifiers(), e->source()); + QApplication::sendEvent(caused, &new_e); + return true; } } caused = next_widget; if (!caused) - handleEnterLeaveEvents(&previousMouseMenu, Q_NULLPTR); + sloppyState.leave(); // Start timers } return false; } @@ -3169,7 +3173,6 @@ void QMenu::enterEvent(QEvent *) Q_D(QMenu); d->hasReceievedEnter = true; d->sloppyState.enter(); - d->sloppyState.startTimer(); d->motions = -1; // force us to ignore the generate mouse move in mouseMoveEvent() } @@ -3180,7 +3183,6 @@ void QMenu::leaveEvent(QEvent *) { Q_D(QMenu); d->hasReceievedEnter = false; - d->sloppyState.leave(); if (!d->activeMenu && d->currentAction) setActiveAction(0); } @@ -3352,10 +3354,18 @@ void QMenu::internalDelayedPopup() const QRect actionRect(d->actionRect(d->currentAction)); const QPoint rightPos(mapToGlobal(QPoint(actionRect.right() + subMenuOffset + 1, actionRect.top()))); - QPoint pos(rightPos); - - d->activeMenu->popup(pos); + d->activeMenu->popup(rightPos); d->sloppyState.setSubMenuPopup(actionRect, d->currentAction, d->activeMenu); + +#if !defined(Q_OS_DARWIN) + // Send the leave event to the current menu - only active popup menu gets + // mouse enter/leave events. Currently Cocoa is an exception, so disable + // it there to avoid event duplication. + if (underMouse()) { + QEvent leaveEvent(QEvent::Leave); + QCoreApplication::sendEvent(this, &leaveEvent); + } +#endif } /*! diff --git a/src/widgets/widgets/qmenu_p.h b/src/widgets/widgets/qmenu_p.h index e717d923ae4..c78abf8aeda 100644 --- a/src/widgets/widgets/qmenu_p.h +++ b/src/widgets/widgets/qmenu_p.h @@ -122,8 +122,6 @@ public: void reset(); bool enabled() const { return m_enabled; } - void setResetAction(QAction *action) { m_reset_action = action; } - enum MouseEventResult { EventIsProcessed, EventShouldBePropagated, @@ -148,22 +146,9 @@ public: } void enter(); + void childEnter(); - void childEnter() - { - stopTimer(); - if (m_parent) - m_parent->childEnter(); - } - - void leave() - { - if (m_dont_start_time_on_leave) - return; - if (m_parent) - m_parent->childLeave(); - startTimer(); - } + void leave(); void childLeave(); static float slope(const QPointF &p1, const QPointF &p2) @@ -189,8 +174,7 @@ public: if (!m_enabled) return EventShouldBePropagated; - if (!m_time.isActive()) - startTimer(); + startTimerIfNotRunning(); if (!m_sub_menu) { reset(); @@ -493,7 +477,6 @@ public: QAction* wceCommands(uint command); #endif QPointer noReplayFor; - static QPointer previousMouseMenu; }; #endif // QT_NO_MENU diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index 34a18354131..50d7b258bc7 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -10358,8 +10358,11 @@ void tst_QWidget::underMouse() QCOMPARE(childWidget2.leaves, 0); // Mouse leaves popup and enters topLevelWidget, should cause leave for popup - // but no enter to topLevelWidget. Again, artificial leave event needed. + // but no enter to topLevelWidget. +#ifdef Q_OS_DARWIN + // Artificial leave event needed for Cocoa. QWindowSystemInterface::handleLeaveEvent(popupWindow); +#endif QTest::mouseMove(popupWindow, popupWindow->mapFromGlobal(window->mapToGlobal(inWindowPoint))); QApplication::processEvents(); QVERIFY(!topLevelWidget.underMouse()); From 46913db2ea68028ddf9cc72378d93ac0d2d80aee Mon Sep 17 00:00:00 2001 From: Vikas Pachdha Date: Wed, 24 Aug 2016 17:35:59 +0200 Subject: [PATCH 22/87] Fixes issue with iOS when project path has a whitespace Task-number: QTBUG-55505 Change-Id: Ic853ecd46a3cb098fff2904119e9002f3add3b8e Reviewed-by: Oswald Buddenhagen --- mkspecs/features/qt.prf | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/mkspecs/features/qt.prf b/mkspecs/features/qt.prf index be08a2a051f..965b6cefc32 100644 --- a/mkspecs/features/qt.prf +++ b/mkspecs/features/qt.prf @@ -203,10 +203,10 @@ contains(qt_module_deps, qml): \ # run qmlimportscanner qtPrepareTool(QMLIMPORTSCANNER, qmlimportscanner, , system) for (QMLPATH, QMLPATHS): \ - IMPORTPATHS += -importPath $$QMLPATH + IMPORTPATHS += -importPath $$system_quote($$QMLPATH) #message(run $$QMLIMPORTSCANNER $$_PRO_FILE_PWD_ $$IMPORTPATHS) - JSON = $$system($$QMLIMPORTSCANNER $$_PRO_FILE_PWD_ $$IMPORTPATHS) + JSON = $$system($$QMLIMPORTSCANNER $$system_quote($$_PRO_FILE_PWD_) $$IMPORTPATHS) parseJson(JSON, IMPORTS)| error("Failed to parse qmlimportscanner output.") @@ -267,13 +267,13 @@ contains(qt_module_deps, qml): \ # But strip away archives and other files that are not needed: !isEmpty(QMAKE_POST_LINK): QMAKE_POST_LINK += ";" QMAKE_POST_LINK += \ - "cp $$OUT_PWD/qt.conf $$qtconfTargetPath; " \ - "test -d $$qmlTargetPath && rm -r $$qmlTargetPath; " \ - "mkdir -p $$qmlTargetPath && " \ + "cp $$shell_quote($$OUT_PWD/qt.conf) \"$$qtconfTargetPath\"; " \ + "test -d \"$$qmlTargetPath\" && rm -r \"$$qmlTargetPath\"; " \ + "mkdir -p \"$$qmlTargetPath\" && " \ "for p in $$QMLPATHS; do" \ "rsync -r --exclude='*.a' --exclude='*.prl' --exclude='*.qmltypes' " - macx-xcode: QMAKE_POST_LINK += "$p/ $$qmlTargetPath; done" - else: QMAKE_POST_LINK += "\$\$p/ $$qmlTargetPath; done" + macx-xcode: QMAKE_POST_LINK += "$p/ \"$$qmlTargetPath\"; done" + else: QMAKE_POST_LINK += "\$\$p/ \"$$qmlTargetPath\"; done" } } } From f4eefce86364112ab215975e0a79755143c20491 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Mon, 22 Feb 2016 09:16:26 +0100 Subject: [PATCH 23/87] Fix typos in highdpi docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I15fd6859ff777388a229e3cb10de45886fe543fb Reviewed-by: Nico Vertriest Reviewed-by: Morten Johan Sørvig --- src/gui/kernel/qhighdpiscaling.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gui/kernel/qhighdpiscaling.cpp b/src/gui/kernel/qhighdpiscaling.cpp index 2d00b9dce91..6846196719a 100644 --- a/src/gui/kernel/qhighdpiscaling.cpp +++ b/src/gui/kernel/qhighdpiscaling.cpp @@ -163,11 +163,11 @@ static inline qreal initialGlobalScaleFactor() The QT_SCALE_FACTOR environment variable can be used to set a global scale factor for all windows in the processs. This is useful for testing and debugging (you can simulate any - devicePixelRatio without needing access to sepcial hardware), + devicePixelRatio without needing access to special hardware), and perhaps also for targeting a specific application to a specific display type (embedded use cases). - 2) A per-screen scale factors + 2) Per-screen scale factors Some platform plugins support providing a per-screen scale factor based on display density information. These platforms include X11, Windows, and Android. @@ -180,13 +180,13 @@ static inline qreal initialGlobalScaleFactor() Enabling either will make QHighDpiScaling call QPlatformScreen::pixelDensity() and use the value provided as the scale factor for the screen in question. Disabling is done on a 'veto' basis where either the - environment or the application source can disable. The intended use + environment or the application can disable the scaling. The intended use cases are 'My system is not providing correct display density information' and 'My application needs to work in display pixels', respectively. The QT_SCREEN_SCALE_FACTORS environment variable can be used to set the screen - scale factors manually.Set this to a semicolon-separated + scale factors manually. Set this to a semicolon-separated list of scale factors (matching the order of QGuiApplications::screens()), or to a list of name=value pairs (where name matches QScreen::name()). From 835d7cf54328bdd93d58bb64ed96a9c322580aea Mon Sep 17 00:00:00 2001 From: Dmitry Shachnev Date: Wed, 7 Sep 2016 17:37:50 +0300 Subject: [PATCH 24/87] QMenuBar: Get rid of QMenuBarPrivate::nativeMenuBar Instead of trying to keep that variable in sync with platformMenuBar state, just check whether platformMenuBar exists instead. Now QMenuBar::isNativeMenuBar() is more reliable, and will not return true if the QPA plugin provides no platform menu bar. Also, remove useless restrictions for code using isNativeMenuBar(). That method is available on all platforms for a long time, not only on macOS or WinCE. This makes sure local menus do not appear if global menus are available, and setVisible(true) is called. Change-Id: I7a5944c64376b4714a38ad981089df8a151c3403 Task-number: QTBUG-54793 Reviewed-by: J-P Nurmi Reviewed-by: Shawn Rutledge --- src/widgets/widgets/qmenubar.cpp | 28 ++++------------------------ src/widgets/widgets/qmenubar_p.h | 4 +--- 2 files changed, 5 insertions(+), 27 deletions(-) diff --git a/src/widgets/widgets/qmenubar.cpp b/src/widgets/widgets/qmenubar.cpp index d7a8ecdae1f..70e8d983db1 100644 --- a/src/widgets/widgets/qmenubar.cpp +++ b/src/widgets/widgets/qmenubar.cpp @@ -1010,13 +1010,11 @@ void QMenuBar::paintEvent(QPaintEvent *e) */ void QMenuBar::setVisible(bool visible) { -#if defined(Q_OS_MAC) || defined(Q_OS_WINCE) if (isNativeMenuBar()) { if (!visible) QWidget::setVisible(false); return; } -#endif QWidget::setVisible(visible); } @@ -1559,11 +1557,7 @@ QRect QMenuBar::actionGeometry(QAction *act) const QSize QMenuBar::minimumSizeHint() const { Q_D(const QMenuBar); -#if defined(Q_OS_MAC) || defined(Q_OS_WINCE) const bool as_gui_menubar = !isNativeMenuBar(); -#else - const bool as_gui_menubar = true; -#endif ensurePolished(); QSize ret(0, 0); @@ -1615,12 +1609,7 @@ QSize QMenuBar::minimumSizeHint() const QSize QMenuBar::sizeHint() const { Q_D(const QMenuBar); -#if defined(Q_OS_MAC) || defined(Q_OS_WINCE) const bool as_gui_menubar = !isNativeMenuBar(); -#else - const bool as_gui_menubar = true; -#endif - ensurePolished(); QSize ret(0, 0); @@ -1673,11 +1662,7 @@ QSize QMenuBar::sizeHint() const int QMenuBar::heightForWidth(int) const { Q_D(const QMenuBar); -#if defined(Q_OS_MAC) || defined(Q_OS_WINCE) const bool as_gui_menubar = !isNativeMenuBar(); -#else - const bool as_gui_menubar = true; -#endif const_cast(d)->updateGeometries(); int height = 0; @@ -1822,10 +1807,8 @@ QWidget *QMenuBar::cornerWidget(Qt::Corner corner) const void QMenuBar::setNativeMenuBar(bool nativeMenuBar) { Q_D(QMenuBar); - if (d->nativeMenuBar == -1 || (nativeMenuBar != bool(d->nativeMenuBar))) { - d->nativeMenuBar = nativeMenuBar; - - if (!d->nativeMenuBar) { + if (nativeMenuBar != bool(d->platformMenuBar)) { + if (!nativeMenuBar) { delete d->platformMenuBar; d->platformMenuBar = 0; } else { @@ -1834,7 +1817,7 @@ void QMenuBar::setNativeMenuBar(bool nativeMenuBar) } updateGeometry(); - if (!d->nativeMenuBar && parentWidget()) + if (!nativeMenuBar && parentWidget()) setVisible(true); } } @@ -1842,10 +1825,7 @@ void QMenuBar::setNativeMenuBar(bool nativeMenuBar) bool QMenuBar::isNativeMenuBar() const { Q_D(const QMenuBar); - if (d->nativeMenuBar == -1) { - return !QApplication::instance()->testAttribute(Qt::AA_DontUseNativeMenuBar); - } - return d->nativeMenuBar; + return bool(d->platformMenuBar); } /*! diff --git a/src/widgets/widgets/qmenubar_p.h b/src/widgets/widgets/qmenubar_p.h index 7ef696f50ec..1b1915843f4 100644 --- a/src/widgets/widgets/qmenubar_p.h +++ b/src/widgets/widgets/qmenubar_p.h @@ -59,7 +59,7 @@ class QMenuBarPrivate : public QWidgetPrivate public: QMenuBarPrivate() : itemsDirty(0), currentAction(0), mouseDown(0), closePopupMode(0), defaultPopDown(1), popupState(0), keyboardState(0), altPressed(0), - nativeMenuBar(-1), doChildEffects(false), platformMenuBar(0) + doChildEffects(false), platformMenuBar(0) #ifdef Q_OS_WINCE , wce_menubar(0), wceClassicMenu(false) @@ -102,8 +102,6 @@ public: uint keyboardState : 1, altPressed : 1; QPointer keyboardFocusWidget; - - int nativeMenuBar : 3; // Only has values -1, 0, and 1 //firing of events void activateAction(QAction *, QAction::ActionEvent); From 63656dbed7bd2b3e35fd8f74a7fb65773baecdd5 Mon Sep 17 00:00:00 2001 From: Dmitry Shachnev Date: Fri, 9 Sep 2016 11:39:10 +0300 Subject: [PATCH 25/87] dbustray: Delete m_notifier in QDBusTrayIcon::cleanup() This fixes a bug where notificationClosed() and actionInvoked() slots were called more than once, from previous alive notifier instances. Change-Id: I4cb4dfc27ee129bc5282fbd8e0961959d0765112 Reviewed-by: Shawn Rutledge --- src/platformsupport/dbustray/qdbustrayicon.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/platformsupport/dbustray/qdbustrayicon.cpp b/src/platformsupport/dbustray/qdbustrayicon.cpp index 4d6e70720d5..859047424da 100644 --- a/src/platformsupport/dbustray/qdbustrayicon.cpp +++ b/src/platformsupport/dbustray/qdbustrayicon.cpp @@ -118,6 +118,8 @@ void QDBusTrayIcon::cleanup() dBusConnection()->unregisterTrayIcon(this); delete m_dbusConnection; m_dbusConnection = Q_NULLPTR; + delete m_notifier; + m_notifier = Q_NULLPTR; m_registered = false; } From 5ca9631d3a0717afb066471ed5eb3b3ed9a9c08a Mon Sep 17 00:00:00 2001 From: Dmitry Shachnev Date: Wed, 7 Sep 2016 17:19:19 +0300 Subject: [PATCH 26/87] =?UTF-8?q?dbusmenu:=20Don=E2=80=99t=20leave=20dangl?= =?UTF-8?q?ing=20pointers=20when=20menus=20are=20destroyed?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Delete references from menu to its containing item, and vice versa. Fixes https://launchpad.net/bugs/1620937 Task-number: QTBUG-55966 Change-Id: I58f0f0a90184bee4b0466c28d91c670a34fa65a5 Reviewed-by: Shawn Rutledge --- src/platformsupport/dbusmenu/qdbusplatformmenu.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/platformsupport/dbusmenu/qdbusplatformmenu.cpp b/src/platformsupport/dbusmenu/qdbusplatformmenu.cpp index 5c259d5b675..a5ee52e73c0 100644 --- a/src/platformsupport/dbusmenu/qdbusplatformmenu.cpp +++ b/src/platformsupport/dbusmenu/qdbusplatformmenu.cpp @@ -60,6 +60,8 @@ QDBusPlatformMenuItem::QDBusPlatformMenuItem(quintptr tag) QDBusPlatformMenuItem::~QDBusPlatformMenuItem() { menuItemsByID.remove(m_dbusID); + if (m_subMenu) + static_cast(m_subMenu)->setContainingMenuItem(Q_NULLPTR); } void QDBusPlatformMenuItem::setTag(quintptr tag) @@ -162,6 +164,8 @@ QDBusPlatformMenu::QDBusPlatformMenu(quintptr tag) QDBusPlatformMenu::~QDBusPlatformMenu() { + if (m_containingMenuItem) + m_containingMenuItem->setMenu(Q_NULLPTR); } void QDBusPlatformMenu::insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *before) From 0dedb603857532b213936c36a1c9e61ba6d3f503 Mon Sep 17 00:00:00 2001 From: Victor Kropp Date: Thu, 4 Aug 2016 16:42:46 +0200 Subject: [PATCH 27/87] Save temp icon in higher resolution on HiDPI screens In case temporary system tray icon is saved to /tmp, scale it according to current devicePixelRatio() instead of using hardcoded 22x22. Change-Id: I2adf2151da3241f4600f8645e323346daabcec4b Reviewed-by: Shawn Rutledge --- src/platformsupport/dbustray/qdbustrayicon.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/platformsupport/dbustray/qdbustrayicon.cpp b/src/platformsupport/dbustray/qdbustrayicon.cpp index da368bf9b77..33e320ad6da 100644 --- a/src/platformsupport/dbustray/qdbustrayicon.cpp +++ b/src/platformsupport/dbustray/qdbustrayicon.cpp @@ -161,9 +161,10 @@ QTemporaryFile *QDBusTrayIcon::tempIcon(const QIcon &icon) } if (!necessary) return Q_NULLPTR; + qreal dpr = qGuiApp->devicePixelRatio(); QTemporaryFile *ret = new QTemporaryFile(TempFileTemplate, this); ret->open(); - icon.pixmap(QSize(22, 22)).save(ret); + icon.pixmap(QSize(22 * dpr, 22 * dpr)).save(ret); ret->close(); return ret; } From c3084f101d5ebb0719b2575663d2d3fdb9266005 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 13 Sep 2016 14:37:19 +0200 Subject: [PATCH 28/87] iOS: accept window modal message dialogs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Although we cannot really show anything but application modal dialogs on iOS, falling back to using non-native dialogs for window modal seems unnecessary strict; In practice you will never have a work flow on iOS where you have several windows visible, and at the same time, need to show a dialog that blocks only one of them. This patch will lift the restriction, and handle window modal as application modal on iOS. Task-number: QTBUG-55909 Change-Id: I581c1a47724ee2bfc2e041672c82c25ed34b2b2d Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosmessagedialog.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/ios/qiosmessagedialog.mm b/src/plugins/platforms/ios/qiosmessagedialog.mm index ac04bf88e1d..50d5442f179 100644 --- a/src/plugins/platforms/ios/qiosmessagedialog.mm +++ b/src/plugins/platforms/ios/qiosmessagedialog.mm @@ -108,7 +108,7 @@ bool QIOSMessageDialog::show(Qt::WindowFlags windowFlags, Qt::WindowModality win Q_UNUSED(windowFlags); if (m_alertController // Ensure that the dialog is not showing already || !options() // Some message dialogs don't have options (QErrorMessage) - || windowModality != Qt::ApplicationModal // We can only do app modal dialogs + || windowModality == Qt::NonModal // We can only do modal dialogs || QSysInfo::MacintoshVersion < QSysInfo::MV_IOS_8_0) // API limitation return false; From 9ff7e7df0ff70f6ff576a9170e6f6c7a5bfce6f2 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Fri, 9 Sep 2016 13:53:23 +0200 Subject: [PATCH 29/87] winrt: Fix touch on Hololens The pressure indicator is not handled for touch on the Hololens causing touch heuristic to fail and not identify the press event. Change-Id: I2aba95fde8aa9abfa3838cad6b3466ff8bc41811 Reviewed-by: Oliver Wolff --- src/plugins/platforms/winrt/qwinrtscreen.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp index ad32c046dfa..849acc2d3f3 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.cpp +++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp @@ -1094,6 +1094,12 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args) properties->get_IsLeftButtonPressed(&isPressed); // IsInContact not reliable on phone #endif + // Devices like the Hololens set a static pressure of 0.5 independent + // of the pressed state. In those cases we need to synthesize the + // pressure value. To our knowledge this does not apply to pens + if (pointerDeviceType == PointerDeviceType_Touch && pressure == 0.5f) + pressure = isPressed ? 1. : 0.; + const QRectF areaRect(area.X * d->scaleFactor, area.Y * d->scaleFactor, area.Width * d->scaleFactor, area.Height * d->scaleFactor); From 1f925d47e9f28e78f0b96dc8a6fd8ed8fde88070 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Wed, 14 Sep 2016 14:29:26 +0200 Subject: [PATCH 30/87] =?UTF-8?q?Blacklist=20modalWindowModallity=20on=20m?= =?UTF-8?q?acOS=20aka=20=E2=80=9Cosx=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Passes locally, unstable on CI. Change-Id: I132268ad0f6ad8b969701c9571fdb609d8225d07 Reviewed-by: Tor Arne Vestbø --- tests/auto/gui/kernel/qwindow/BLACKLIST | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/auto/gui/kernel/qwindow/BLACKLIST b/tests/auto/gui/kernel/qwindow/BLACKLIST index 0fe40e8db39..93b7310d10e 100644 --- a/tests/auto/gui/kernel/qwindow/BLACKLIST +++ b/tests/auto/gui/kernel/qwindow/BLACKLIST @@ -10,3 +10,5 @@ ubuntu-14.04 ubuntu-14.04 [modalDialogClosingOneOfTwoModal] osx +[modalWindowModallity] +osx From 43d935aa2d0fd5749fea717d4aa576cf52a05c5a Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Wed, 14 Sep 2016 13:36:06 +0200 Subject: [PATCH 31/87] QMenuBar: improve documentation of the D-Bus unified menu bar Since 5.7.0 this is not just a macOS feature. It's also not necessarily limited to Ubuntu Unity, since the specification is open, and there's work in progress to implement it on KDE. Also fixed a couple of typos. Task-number: QTBUG-54793 Change-Id: Idbc68ddafff4dea30649e634ca29f10703f60d3b Reviewed-by: Jake Petroules --- src/widgets/widgets/qmenubar.cpp | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/widgets/widgets/qmenubar.cpp b/src/widgets/widgets/qmenubar.cpp index b6597df47c6..0e7b25f65db 100644 --- a/src/widgets/widgets/qmenubar.cpp +++ b/src/widgets/widgets/qmenubar.cpp @@ -616,9 +616,10 @@ void QMenuBar::initStyleOption(QStyleOptionMenuItem *option, const QAction *acti for items in the menu bar are only shown when the \uicontrol{Alt} key is pressed. - \section1 QMenuBar on \macos + \section1 QMenuBar as a Global Menu Bar - QMenuBar on \macos is a wrapper for using the system-wide menu bar. + On \macos and on certain Linux desktop environments such as + Ubuntu Unity, QMenuBar is a wrapper for using the system-wide menu bar. If you have multiple menu bars in one dialog the outermost menu bar (normally inside a widget with widget flag Qt::Window) will be used for the system-wide menu bar. @@ -661,11 +662,16 @@ void QMenuBar::initStyleOption(QStyleOptionMenuItem *option, const QAction *acti as its parent. That menu bar would only be displayed for the parent QMainWindow. - \b{Note:} The text used for the application name in the menu + \b{Note:} The text used for the application name in the \macos menu bar is obtained from the value set in the \c{Info.plist} file in the application's bundle. See \l{Qt for macOS - Deployment} for more information. + \b{Note:} On Linux, if the com.canonical.AppMenu.Registrar + service is available on the D-Bus session bus, then Qt will + communicate with it to install the application's menus into the + global menu bar, as described. + \section1 Examples The \l{mainwindows/menus}{Menus} example shows how to use QMenuBar @@ -1809,14 +1815,16 @@ QWidget *QMenuBar::cornerWidget(Qt::Corner corner) const \brief Whether or not a menubar will be used as a native menubar on platforms that support it \since 4.6 - This property specifies whether or not the menubar should be used as a native menubar on \macos. + This property specifies whether or not the menubar should be used as a native menubar on + platforms that support it. The currently supported platforms are \macos, and + Linux desktops which use the com.canonical.dbusmenu D-Bus interface (such as Ubuntu Unity). If this property is \c true, the menubar is used in the native menubar and is not in the window of - its parent, if \c false the menubar remains in the window. On other platforms the value of this - attribute has no effect. + its parent; if \c false the menubar remains in the window. On other platforms, + setting this attribute has no effect, and reading this attribute will always return \c false. The default is to follow whether the Qt::AA_DontUseNativeMenuBar attribute - is set for the application. Explicitly settings this property overrides - the presence (or abscence) of the attribute. + is set for the application. Explicitly setting this property overrides + the presence (or absence) of the attribute. */ void QMenuBar::setNativeMenuBar(bool nativeMenuBar) From c59c759fcccd17b06255e7062cc1ceb532912a8a Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 15 Sep 2016 09:07:53 -0700 Subject: [PATCH 32/87] Suppress ICC warning #111 about unreachable code in toWCharArray qstring.h(961): warning #111: statement is unreachable Change-Id: I33dc971f005a4848bb8ffffd14748ae03dadefc9 Reviewed-by: Marc Mutz --- src/corelib/tools/qstring.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h index 58ad2caa2b4..4863b1d2c5b 100644 --- a/src/corelib/tools/qstring.h +++ b/src/corelib/tools/qstring.h @@ -947,6 +947,7 @@ inline QString QString::section(QChar asep, int astart, int aend, SectionFlags a QT_WARNING_PUSH QT_WARNING_DISABLE_MSVC(4127) // "conditional expression is constant" +QT_WARNING_DISABLE_INTEL(111) // "statement is unreachable" inline int QString::toWCharArray(wchar_t *array) const { From 469d68b344380c1a9ccef95bb784b39a436a7634 Mon Sep 17 00:00:00 2001 From: Sune Vuorela Date: Sun, 4 Sep 2016 14:59:37 +0200 Subject: [PATCH 33/87] Fix handling of bad compose table MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ASAN talk at QtCon was pointing out a out of bound read in a vector. Let's try to do something about it. If the lazy initialization of compose table fails, the first character handling still tries to actually access it. Later characters are properly handled in the caller. Reported-by: Hanno Böck Change-Id: Ieac3e95361abd0fcd06c555bcd00ca1c4d8f1931 Reviewed-by: Thiago Macieira --- .../compose/qcomposeplatforminputcontext.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp index d1bea9af23f..fb404802039 100644 --- a/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp +++ b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp @@ -162,11 +162,19 @@ bool QComposeInputContext::checkComposeTable() TableGenerator reader; m_tableState = reader.tableState(); - if ((m_tableState & TableGenerator::NoErrors) == TableGenerator::NoErrors) - m_composeTable = reader.composeTable(); - m_compositionTableInitialized = true; + if ((m_tableState & TableGenerator::NoErrors) == TableGenerator::NoErrors) { + m_composeTable = reader.composeTable(); + } else { +#ifdef DEBUG_COMPOSING + qDebug( "### FAILED_PARSING ###" ); +#endif + // if we have errors, don' try to look things up anyways. + reset(); + return false; + } } + Q_ASSERT(!m_composeTable.isEmpty()); QVector::const_iterator it = std::lower_bound(m_composeTable.constBegin(), m_composeTable.constEnd(), m_composeBuffer, Compare()); From 2c9d15d73c5136dd2b8a28d7ff8fef2b81d4c5dc Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 19 Aug 2016 15:07:57 +0200 Subject: [PATCH 34/87] fix QMAKE_DEFAULT_*DIRS resolution with apple SDK the code got factored out to an own toolchain.prf file, which is load()ed from default_pre.prf, so no change at first. however, on mac, we shadow toolchain.prf, and make it load() sdk.prf first. a side effect of this is that project files may not override QMAKE_MAC_SDK any more, which seems to be no big loss. it is still possible to override the sdk on the configure command line (but note that this only ever worked for the target sdk). it has also become harder to disable the use of an sdk altogether: putting CONFIG-=sdk into a project file or the qmake command line has no effect now. instead, it's possible to put it into .qmake.{conf,cache}. to make it simpler again, it's conceivable to finally add qmake -pre, which would allow setting variables before default_pre.prf is executed. Change-Id: I149e0540c00745fe8119fffd146283bb214f22ec Reviewed-by: Thiago Macieira --- mkspecs/common/mac.conf | 2 ++ mkspecs/features/default_pre.prf | 42 +-------------------------- mkspecs/features/mac/default_post.prf | 4 --- mkspecs/features/mac/default_pre.prf | 2 +- mkspecs/features/mac/toolchain.prf | 5 ++++ mkspecs/features/toolchain.prf | 42 +++++++++++++++++++++++++++ 6 files changed, 51 insertions(+), 46 deletions(-) create mode 100644 mkspecs/features/mac/toolchain.prf create mode 100644 mkspecs/features/toolchain.prf diff --git a/mkspecs/common/mac.conf b/mkspecs/common/mac.conf index d267d1f10d3..b19b0853cb2 100644 --- a/mkspecs/common/mac.conf +++ b/mkspecs/common/mac.conf @@ -8,6 +8,8 @@ QMAKE_PLATFORM += mac darwin include(unix.conf) +CONFIG += sdk + QMAKE_RESOURCE = /Developer/Tools/Rez QMAKE_EXTENSION_SHLIB = dylib QMAKE_LIBDIR = diff --git a/mkspecs/features/default_pre.prf b/mkspecs/features/default_pre.prf index 62cd90912ee..cd4ea58d87d 100644 --- a/mkspecs/features/default_pre.prf +++ b/mkspecs/features/default_pre.prf @@ -25,44 +25,4 @@ contains(QT_CONFIG, c++11):lessThan(QT_COMPILER_STDCXX, 201103): CONFIG += c++11 unset(today) } -isEmpty(QMAKE_DEFAULT_INCDIRS):!host_build { - # - # Get default include and library paths from compiler - # - gcc { - !equals(QMAKE_HOST.os, Windows) { - cmd_prefix = "LC_ALL=C" - cmd_suffix = "/dev/null" - } else { - cmd_prefix = "set LC_ALL=C&" - cmd_suffix = "NUL" - } - output = $$system("$$cmd_prefix $$QMAKE_CXX $$QMAKE_CXXFLAGS -xc++ -E -v - 2>&1 $$cmd_suffix", lines) - add_includes = false - for (line, output) { - line ~= s/^ *// # remove leading spaces - contains(line, "LIBRARY_PATH=.*") { - line ~= s/^LIBRARY_PATH=// # remove leading LIBRARY_PATH= - paths = $$split(line, $$QMAKE_DIRLIST_SEP) - for (path, paths): \ - QMAKE_DEFAULT_LIBDIRS += $$clean_path($$path) - } else: contains(line, "$${LITERAL_HASH}include <.*") { # #include <...> search starts here: - add_includes = true - } else: contains(line, "End of search.*") { - add_includes = false - } else: $$add_includes { - !contains(line, ".* \\(framework directory\\)"): \ - QMAKE_DEFAULT_INCDIRS += $$clean_path($$line) - } - } - QMAKE_DEFAULT_LIBDIRS = $$unique(QMAKE_DEFAULT_LIBDIRS) - } - - unix { - isEmpty(QMAKE_DEFAULT_INCDIRS): QMAKE_DEFAULT_INCDIRS = /usr/include /usr/local/include - isEmpty(QMAKE_DEFAULT_LIBDIRS): QMAKE_DEFAULT_LIBDIRS = /lib /usr/lib - } - - !isEmpty(QMAKE_DEFAULT_INCDIRS): cache(QMAKE_DEFAULT_INCDIRS, set stash) - !isEmpty(QMAKE_DEFAULT_LIBDIRS): cache(QMAKE_DEFAULT_LIBDIRS, set stash) -} +load(toolchain) diff --git a/mkspecs/features/mac/default_post.prf b/mkspecs/features/mac/default_post.prf index 30960e66ddc..6e920cd7d3f 100644 --- a/mkspecs/features/mac/default_post.prf +++ b/mkspecs/features/mac/default_post.prf @@ -35,7 +35,3 @@ cache(QMAKE_XCODE_DEVELOPER_PATH, stash) cache(QMAKE_XCODE_VERSION, stash) QMAKE_XCODE_LIBRARY_SUFFIX = $$qtPlatformTargetSuffix() - -# Ensure that we process sdk.prf first, as it will update QMAKE_CXX -# and friends that other features/extra compilers may depend on. -sdk: load(sdk) diff --git a/mkspecs/features/mac/default_pre.prf b/mkspecs/features/mac/default_pre.prf index 5df99d1acde..1190efed5dd 100644 --- a/mkspecs/features/mac/default_pre.prf +++ b/mkspecs/features/mac/default_pre.prf @@ -1,4 +1,4 @@ -CONFIG = sdk rez $$CONFIG +CONFIG = rez $$CONFIG load(default_pre) isEmpty(QMAKE_XCODE_DEVELOPER_PATH) { diff --git a/mkspecs/features/mac/toolchain.prf b/mkspecs/features/mac/toolchain.prf new file mode 100644 index 00000000000..df191eb13c4 --- /dev/null +++ b/mkspecs/features/mac/toolchain.prf @@ -0,0 +1,5 @@ +# Ensure that we process sdk.prf first, as it will update QMAKE_CXX, +# which the default path determination uses. +sdk: load(sdk) + +load(toolchain) diff --git a/mkspecs/features/toolchain.prf b/mkspecs/features/toolchain.prf new file mode 100644 index 00000000000..7691b7db343 --- /dev/null +++ b/mkspecs/features/toolchain.prf @@ -0,0 +1,42 @@ + +isEmpty(QMAKE_DEFAULT_INCDIRS):!host_build { + # + # Get default include and library paths from compiler + # + gcc { + !equals(QMAKE_HOST.os, Windows) { + cmd_prefix = "LC_ALL=C" + cmd_suffix = "/dev/null" + } else { + cmd_prefix = "set LC_ALL=C&" + cmd_suffix = "NUL" + } + output = $$system("$$cmd_prefix $$QMAKE_CXX $$QMAKE_CXXFLAGS -xc++ -E -v - 2>&1 $$cmd_suffix", lines) + add_includes = false + for (line, output) { + line ~= s/^ *// # remove leading spaces + contains(line, "LIBRARY_PATH=.*") { + line ~= s/^LIBRARY_PATH=// # remove leading LIBRARY_PATH= + paths = $$split(line, $$QMAKE_DIRLIST_SEP) + for (path, paths): \ + QMAKE_DEFAULT_LIBDIRS += $$clean_path($$path) + } else: contains(line, "$${LITERAL_HASH}include <.*") { # #include <...> search starts here: + add_includes = true + } else: contains(line, "End of search.*") { + add_includes = false + } else: $$add_includes { + !contains(line, ".* \\(framework directory\\)"): \ + QMAKE_DEFAULT_INCDIRS += $$clean_path($$line) + } + } + QMAKE_DEFAULT_LIBDIRS = $$unique(QMAKE_DEFAULT_LIBDIRS) + } + + unix { + isEmpty(QMAKE_DEFAULT_INCDIRS): QMAKE_DEFAULT_INCDIRS = /usr/include /usr/local/include + isEmpty(QMAKE_DEFAULT_LIBDIRS): QMAKE_DEFAULT_LIBDIRS = /lib /usr/lib + } + + !isEmpty(QMAKE_DEFAULT_INCDIRS): cache(QMAKE_DEFAULT_INCDIRS, set stash) + !isEmpty(QMAKE_DEFAULT_LIBDIRS): cache(QMAKE_DEFAULT_LIBDIRS, set stash) +} From 8ceab12814a7437a01d917c83ec28fd6e81c459e Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 8 Sep 2016 13:56:16 -0700 Subject: [PATCH 35/87] Fake exporting of the QDBusUtil namespace It's a namespace containing only private things, but some of those get used in some QtDBus tools. By adding a macro that expands to nothing, findclasslist.pl will notice the namespace and add it to the ELF version script. Task-number: QTBUG-55897 Change-Id: I371f5b01e24a4d56b304fffd1472748cde56f0c3 Reviewed-by: Oswald Buddenhagen --- src/dbus/qdbusutil_p.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/dbus/qdbusutil_p.h b/src/dbus/qdbusutil_p.h index e11fe573b5f..4331fdb1d1b 100644 --- a/src/dbus/qdbusutil_p.h +++ b/src/dbus/qdbusutil_p.h @@ -64,7 +64,8 @@ QT_BEGIN_NAMESPACE -namespace QDBusUtil +#define Q_DBUS_NO_EXPORT // force findclasslist.pl looking into this namespace +namespace Q_DBUS_NO_EXPORT QDBusUtil { Q_DBUS_EXPORT bool isValidInterfaceName(const QString &ifaceName); From ebf0b121084822ce754c14ed7255bde0f90bf42f Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 6 Sep 2016 11:41:00 -0700 Subject: [PATCH 36/87] Make QDBusConnectionPrivate::relaySignal be called in the right thread This function sends D-Bus messages directly (in huntAndEmit), so it should only be called from the QDBusConnectionManager thread. Somehow, I missed this in the Qt 5.6 refactoring of QtDBus. Being called in the wrong thread means that there's a visible behavior change compared to Qt 5.5: if the user code sent a method call or method return/error and then emitted a signal, we'd have two threads racing to send the D-Bus messages. This was observed in Telepathy-Qt code: certain signals arrived before a method return, even though they were clearly emitted by a queued QMetaObject::invokeMethod. In addition to that, we have has an internal problem (though not observed): the libdbus-1 timer and socket callbacks would be called in the wrong thread and we no longer have protection against that. Unit testing not possible since this is a race condition. Change-Id: I9e96ecd4f6aa4ff0ae08fffd1471d002142613d6 Reviewed-by: Gustavo Pichorim Boiko Reviewed-by: Alex Blasche --- src/dbus/qdbusintegrator.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index 878a58294c5..c2cf7f41e4e 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -1257,6 +1257,7 @@ void QDBusConnectionPrivate::relaySignal(QObject *obj, const QMetaObject *mo, in break; } + checkThread(); QDBusReadLocker locker(RelaySignalAction, this); QDBusMessage message = QDBusMessage::createSignal(QLatin1String("/"), interface, QLatin1String(memberName)); @@ -2368,12 +2369,9 @@ void QDBusConnectionPrivate::registerObject(const ObjectTreeNode *node) connector->connectAllSignals(node->obj); } - // disconnect and reconnect to avoid duplicates - connector->disconnect(SIGNAL(relaySignal(QObject*,const QMetaObject*,int,QVariantList)), - this, SLOT(relaySignal(QObject*,const QMetaObject*,int,QVariantList))); connect(connector, SIGNAL(relaySignal(QObject*,const QMetaObject*,int,QVariantList)), this, SLOT(relaySignal(QObject*,const QMetaObject*,int,QVariantList)), - Qt::DirectConnection); + Qt::ConnectionType(Qt::QueuedConnection | Qt::UniqueConnection)); } } From 2ccf6c60d993714ed8efbb860dd03bc07db197ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Molinari?= Date: Thu, 1 Sep 2016 19:13:32 +0200 Subject: [PATCH 37/87] Fix the GCC version supporting -Wsuggest-override Q_CC_GNU is (__GNUC__ * 100 + __GNUC_MINOR__), so 510 is 5.10 not 5.1.0. The first GCC 5 release has support for -Wsuggest-override, so it should really be 501. Change-Id: I7b264af087cd4562ce8720c99b70116d7654ea5f Reviewed-by: Thiago Macieira --- src/corelib/kernel/qobjectdefs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/kernel/qobjectdefs.h b/src/corelib/kernel/qobjectdefs.h index 0a4492dcda6..3c6ecf7c9e0 100644 --- a/src/corelib/kernel/qobjectdefs.h +++ b/src/corelib/kernel/qobjectdefs.h @@ -173,7 +173,7 @@ inline void qYouForgotTheQ_OBJECT_Macro(T1, T2) {} #if defined(Q_CC_CLANG) && Q_CC_CLANG >= 306 # define Q_OBJECT_NO_OVERRIDE_WARNING QT_WARNING_DISABLE_CLANG("-Winconsistent-missing-override") -#elif defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && Q_CC_GNU >= 510 +#elif defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && Q_CC_GNU >= 501 # define Q_OBJECT_NO_OVERRIDE_WARNING QT_WARNING_DISABLE_GCC("-Wsuggest-override") #else # define Q_OBJECT_NO_OVERRIDE_WARNING From f1e87dc9bcc1f9d12183736dfa29a46df5930088 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 15 Sep 2016 15:25:01 +0200 Subject: [PATCH 38/87] QTableGenerator: Fix uninit'ed values It's probably benign, but it causes Corverity to complain, so always init all fields of QComposeCacheFileHeader. Format the code so it can easily be ported to uniform init later on. Coverity-Id: 93043 Change-Id: Ifa1ccc3fa58dc813306917f216772fd24d4930c9 Reviewed-by: Thiago Macieira --- .../compose/generator/qtablegenerator.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp index 44f1d7e6bab..338c7ca3be5 100644 --- a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp +++ b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp @@ -106,15 +106,15 @@ static QByteArray localHostName() */ static QComposeCacheFileHeader readFileMetadata(const QString &path) { - QComposeCacheFileHeader info; - info.reserved = 0; - info.fileSize = 0; + quint64 fileSize = 0; + qint64 lastModified = 0; const QByteArray pathBytes = QFile::encodeName(path); QT_STATBUF st; - if (QT_STAT(pathBytes.data(), &st) != 0) - return info; - info.lastModified = st.st_mtime; - info.fileSize = st.st_size; + if (QT_STAT(pathBytes.data(), &st) == 0) { + lastModified = st.st_mtime; + fileSize = st.st_size; + } + QComposeCacheFileHeader info = { 0, 0, fileSize, lastModified }; return info; } From 47d064e905de29153d3930dfbbe9b07cd2aa0e05 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 15 Sep 2016 17:58:59 +0200 Subject: [PATCH 39/87] libjpeg config test: init variable Yes, yes, this is just a configure test, but why do something stupid in the code and then have to shut up Coverity manually? Fix by making it a global, which means it will be zero-initialized (I didn't want to do the obvious = 0, as that could protentially create a "0 used as nullptr" warning at some point in the future. Coverity-Id: 59485 Change-Id: I49ecd28be983a0e42b420d20da0db34a872c6f44 Reviewed-by: Thiago Macieira --- config.tests/unix/libjpeg/libjpeg.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/config.tests/unix/libjpeg/libjpeg.cpp b/config.tests/unix/libjpeg/libjpeg.cpp index 68c11e1335b..4432603b841 100644 --- a/config.tests/unix/libjpeg/libjpeg.cpp +++ b/config.tests/unix/libjpeg/libjpeg.cpp @@ -37,9 +37,10 @@ extern "C" { #include } +j_compress_ptr cinfo; + int main(int, char **) { - j_compress_ptr cinfo; jpeg_create_compress(cinfo); return 0; } From f242b91189e3bd0cc96dd1a2695eef0521099aea Mon Sep 17 00:00:00 2001 From: Jake Petroules Date: Wed, 14 Sep 2016 11:36:45 -0700 Subject: [PATCH 40/87] Fix code signing for qmake-generated Xcode projects in Xcode 8 Task-number: QTBUG-55915 Change-Id: I7cbddd7ed8a6e0fa220b423e11e4d550e09297f9 Reviewed-by: Louai Al-Khanji --- qmake/generators/mac/pbuilder_pbx.cpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp index 75abc4378f4..5e37cd65d85 100644 --- a/qmake/generators/mac/pbuilder_pbx.cpp +++ b/qmake/generators/mac/pbuilder_pbx.cpp @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -1405,6 +1406,28 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) QString configName = (as_release ? "Release" : "Debug"); QMap settings; + if (!project->isActiveConfig("no_xcode_development_team")) { + const QSettings xcodeSettings( + QDir::homePath() + QLatin1String("/Library/Preferences/com.apple.dt.Xcode.plist"), + QSettings::NativeFormat); + const QVariantMap teams = xcodeSettings.value(QLatin1String("IDEProvisioningTeams")).toMap(); + if (!teams.isEmpty()) { + for (QVariantMap::const_iterator it = teams.begin(), end = teams.end(); it != end; ++it) { + const QVariantMap team = it.value().toMap(); + const QString teamType = team.value(QLatin1String("teamType")).toString(); + + // Skip Company teams because signing permissions may not be available under all + // circumstances for users who are not the Team Agent + if (teamType != QLatin1String("Company")) { + const QString teamId = team.value(QLatin1String("teamID")).toString(); + settings.insert("DEVELOPMENT_TEAM", teamId); + + // first suitable team we found is the one we'll use by default + break; + } + } + } + } settings.insert("COPY_PHASE_STRIP", (as_release ? "YES" : "NO")); // Bitcode is only supported with a deployment target >= iOS 6.0. // Disable it for now, and consider switching it on when later From 2c48695f04b0f4b3b11ec037b13132b146cad082 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Thu, 15 Sep 2016 23:21:15 +0200 Subject: [PATCH 41/87] XCB Drop from external app: fix keyboard modifier state Fix inspired by Qt 4 sources. When we get drop events that are not coming from the same application, it's unlikely that the keyboard modifiers are in a sensible state (the usual XCB events are not sent during drag and drop), so set the keyboard modifier state explicitly. Task-number: QTBUG-49645 Change-Id: I9360f2b7ffeaa5243a4dfe7ccf96df134c5d2156 Reviewed-by: Shawn Rutledge Reviewed-by: Laszlo Agocs --- src/plugins/platforms/xcb/qxcbdrag.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp index f93e420bcf4..acfb580b944 100644 --- a/src/plugins/platforms/xcb/qxcbdrag.cpp +++ b/src/plugins/platforms/xcb/qxcbdrag.cpp @@ -960,6 +960,9 @@ void QXcbDrag::handleDrop(QPlatformWindow *, const xcb_client_message_event_t *e } else { dropData = platformDropData(); supported_drop_actions = accepted_drop_action; + + // Drop coming from another app? Update keyboard modifiers. + QGuiApplicationPrivate::modifier_buttons = QGuiApplication::queryKeyboardModifiers(); } if (!dropData) From a95d81e786ea839e59d6d6594c7d648b78a3c226 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Thu, 8 Sep 2016 18:57:46 +0200 Subject: [PATCH 42/87] Q(Date|Time)+::(to|from)String(): mention relevant QLocale methods The const QString &format variants of these methods lack adequate control over the locale used; the Qt::DateFormat variants give only limited control over the format string. So reference the QLocale methods that provide the general case, in the docs of each. Also made the \sa cross-referencing among these methods a little more coherent. Task-number: QTBUG-55632 Change-Id: Icd0c8548045e74879e941ba089c3bdea78f14e34 Reviewed-by: Thiago Macieira --- src/corelib/tools/qdatetime.cpp | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index e6d0b978361..6b09b4107cb 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -842,7 +842,7 @@ static QString toStringIsoDate(qint64 jd) range 0 to 9999. This restriction may apply to locale-aware formats as well, depending on the locale settings. - \sa shortDayName(), shortMonthName() + \sa fromString(), shortDayName(), shortMonthName(), QLocale::toString() */ QString QDate::toString(Qt::DateFormat format) const { @@ -918,7 +918,7 @@ QString QDate::toString(Qt::DateFormat format) const If the datetime is invalid, an empty string will be returned. - \sa QDateTime::toString(), QTime::toString(), QLocale::toString() + \sa fromString(), QDateTime::toString(), QTime::toString(), QLocale::toString() */ QString QDate::toString(const QString& format) const @@ -1185,6 +1185,8 @@ qint64 QDate::daysTo(const QDate &d) const Note for Qt::TextDate: It is recommended that you use the English short month names (e.g. "Jan"). Although localized month names can also be used, they depend on the user's locale settings. + + \sa toString(), QLocale::toDate() */ QDate QDate::fromString(const QString& string, Qt::DateFormat format) { @@ -1303,8 +1305,8 @@ QDate QDate::fromString(const QString& string, Qt::DateFormat format) \snippet code/src_corelib_tools_qdatetime.cpp 3 - \sa QDateTime::fromString(), QTime::fromString(), QDate::toString(), - QDateTime::toString(), QTime::toString() + \sa toString(), QDateTime::fromString(), QTime::fromString(), + QLocale::toDate() */ QDate QDate::fromString(const QString &string, const QString &format) @@ -1571,7 +1573,7 @@ int QTime::msec() const If the time is invalid, an empty string will be returned. - \sa QDate::toString(), QDateTime::toString() + \sa fromString(), QDate::toString(), QDateTime::toString(), QLocale::toString() */ QString QTime::toString(Qt::DateFormat format) const @@ -1644,7 +1646,7 @@ QString QTime::toString(Qt::DateFormat format) const If the time is invalid, an empty string will be returned. If \a format is empty, the default format "hh:mm:ss" is used. - \sa QDate::toString(), QDateTime::toString(), QLocale::toString() + \sa fromString(), QDate::toString(), QDateTime::toString(), QLocale::toString() */ QString QTime::toString(const QString& format) const { @@ -1929,6 +1931,8 @@ static QTime fromIsoTimeString(const QStringRef &string, Qt::DateFormat format, this may result in two conversion attempts (if the conversion fails for the default locale). This should be considered an implementation detail. + + \sa toString(), QLocale::toTime() */ QTime QTime::fromString(const QString& string, Qt::DateFormat format) { @@ -2002,8 +2006,8 @@ QTime QTime::fromString(const QString& string, Qt::DateFormat format) \snippet code/src_corelib_tools_qdatetime.cpp 8 - \sa QDateTime::fromString(), QDate::fromString(), QDate::toString(), - QDateTime::toString(), QTime::toString() + \sa toString(), QDateTime::fromString(), QDate::fromString(), + QLocale::toTime() */ QTime QTime::fromString(const QString &string, const QString &format) @@ -3520,7 +3524,8 @@ void QDateTime::setTime_t(uint secsSince1Jan1970UTC) range 0 to 9999. This restriction may apply to locale-aware formats as well, depending on the locale settings. - \sa QDate::toString(), QTime::toString(), Qt::DateFormat + \sa fromString(), QDate::toString(), QTime::toString(), + QLocale::toString() */ QString QDateTime::toString(Qt::DateFormat format) const @@ -3660,7 +3665,7 @@ QString QDateTime::toString(Qt::DateFormat format) const If the datetime is invalid, an empty string will be returned. - \sa QDate::toString(), QTime::toString(), QLocale::toString() + \sa fromString(), QDate::toString(), QTime::toString(), QLocale::toString() */ QString QDateTime::toString(const QString& format) const { @@ -4356,6 +4361,8 @@ int QDateTime::utcOffset() const Note for Qt::TextDate: It is recommended that you use the English short month names (e.g. "Jan"). Although localized month names can also be used, they depend on the user's locale settings. + + \sa toString(), QLocale::toDateTime() */ QDateTime QDateTime::fromString(const QString& string, Qt::DateFormat format) { @@ -4657,8 +4664,8 @@ QDateTime QDateTime::fromString(const QString& string, Qt::DateFormat format) \snippet code/src_corelib_tools_qdatetime.cpp 14 - \sa QDate::fromString(), QTime::fromString(), QDate::toString(), - QDateTime::toString(), QTime::toString() + \sa toString(), QDate::fromString(), QTime::fromString(), + QLocale::toDateTime() */ QDateTime QDateTime::fromString(const QString &string, const QString &format) From 71e195f6ef2f4ba1822353fd46124b166187c70f Mon Sep 17 00:00:00 2001 From: James McDonnell Date: Thu, 25 Aug 2016 10:55:35 -0400 Subject: [PATCH 43/87] Reverse the flush-screen-context test It was backwards so the screen context was being flushed on every screen interaction when the parameter was _not_ specified. During mouse/touch movement, the number of flushes can be so great that it negatively impacts performance. Change-Id: I4dfe9c33c8ce31237db1d78db1cb8e04c00c4dd3 Reviewed-by: Dan Cape Reviewed-by: Rafael Roquetto --- src/plugins/platforms/qnx/qqnxintegration.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/qnx/qqnxintegration.cpp b/src/plugins/platforms/qnx/qqnxintegration.cpp index 6548c82310c..621a96a3cf1 100644 --- a/src/plugins/platforms/qnx/qqnxintegration.cpp +++ b/src/plugins/platforms/qnx/qqnxintegration.cpp @@ -116,7 +116,7 @@ static inline QQnxIntegration::Options parseOptions(const QStringList ¶mList options |= QQnxIntegration::FullScreenApplication; } - if (!paramList.contains(QLatin1String("flush-screen-context"))) { + if (paramList.contains(QLatin1String("flush-screen-context"))) { options |= QQnxIntegration::AlwaysFlushScreenContext; } From 8a2401bd45bb5991cf4c6a69539cb58f72e19994 Mon Sep 17 00:00:00 2001 From: James McDonnell Date: Tue, 26 Jul 2016 16:33:47 -0400 Subject: [PATCH 44/87] Switch to 7.0 screen property names The names of some screen properties have changed in 7.0. For 6.6, map the 7.0 names to 6.6 names. Change-Id: Iaf9d297fdd6a0329a84150f2b9a27665d89cc1ec Reviewed-by: Dan Cape Reviewed-by: Rafael Roquetto --- src/plugins/platforms/qnx/qqnxscreen.h | 11 +++++++++++ src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp | 12 ++++++------ src/plugins/platforms/qnx/qqnxwindow.cpp | 2 +- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/plugins/platforms/qnx/qqnxscreen.h b/src/plugins/platforms/qnx/qqnxscreen.h index 00176ac32c9..8a6e2bbcac0 100644 --- a/src/plugins/platforms/qnx/qqnxscreen.h +++ b/src/plugins/platforms/qnx/qqnxscreen.h @@ -43,6 +43,17 @@ #include +// For pre-7.0 SDPs, map some screen property names to the old +// names. +#include +#if _NTO_VERSION < 700 +const int SCREEN_PROPERTY_FLAGS = SCREEN_PROPERTY_KEY_FLAGS; +const int SCREEN_PROPERTY_FOCUS = SCREEN_PROPERTY_KEYBOARD_FOCUS; +const int SCREEN_PROPERTY_MODIFIERS = SCREEN_PROPERTY_KEY_MODIFIERS; +const int SCREEN_PROPERTY_SCAN = SCREEN_PROPERTY_KEY_SCAN; +const int SCREEN_PROPERTY_SYM = SCREEN_PROPERTY_KEY_SYM; +#endif + QT_BEGIN_NAMESPACE class QQnxWindow; diff --git a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp index 6c9532c4288..09585b1aacc 100644 --- a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp +++ b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp @@ -233,20 +233,20 @@ void QQnxScreenEventHandler::handleKeyboardEvent(screen_event_t event) { // get flags of key event int flags; - Q_SCREEN_CHECKERROR(screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_FLAGS, &flags), + Q_SCREEN_CHECKERROR(screen_get_event_property_iv(event, SCREEN_PROPERTY_FLAGS, &flags), "Failed to query event flags"); // get key code int sym; - Q_SCREEN_CHECKERROR(screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_SYM, &sym), + Q_SCREEN_CHECKERROR(screen_get_event_property_iv(event, SCREEN_PROPERTY_SYM, &sym), "Failed to query event sym"); int modifiers; - Q_SCREEN_CHECKERROR(screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_MODIFIERS, &modifiers), + Q_SCREEN_CHECKERROR(screen_get_event_property_iv(event, SCREEN_PROPERTY_MODIFIERS, &modifiers), "Failed to query event modifieres"); int scan; - Q_SCREEN_CHECKERROR(screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_SCAN, &scan), + Q_SCREEN_CHECKERROR(screen_get_event_property_iv(event, SCREEN_PROPERTY_SCAN, &scan), "Failed to query event scan"); int cap; @@ -593,7 +593,7 @@ void QQnxScreenEventHandler::handlePropertyEvent(screen_event_t event) qFatal("QQnx: failed to query window property, errno=%d", errno); switch (property) { - case SCREEN_PROPERTY_KEYBOARD_FOCUS: + case SCREEN_PROPERTY_FOCUS: handleKeyboardFocusPropertyEvent(window); break; default: @@ -606,7 +606,7 @@ void QQnxScreenEventHandler::handleKeyboardFocusPropertyEvent(screen_window_t wi { errno = 0; int focus = 0; - if (window && screen_get_window_property_iv(window, SCREEN_PROPERTY_KEYBOARD_FOCUS, &focus) != 0) + if (window && screen_get_window_property_iv(window, SCREEN_PROPERTY_FOCUS, &focus) != 0) qFatal("QQnx: failed to query keyboard focus property, errno=%d", errno); QWindow *focusWindow = QQnxIntegration::window(window); diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp index da2929d4c0a..bb953427269 100644 --- a/src/plugins/platforms/qnx/qqnxwindow.cpp +++ b/src/plugins/platforms/qnx/qqnxwindow.cpp @@ -581,7 +581,7 @@ void QQnxWindow::setFocus(screen_window_t newFocusWindow) screen_get_window_property_pv(nativeHandle(), SCREEN_PROPERTY_GROUP, reinterpret_cast(&screenGroup)); if (screenGroup) { - screen_set_group_property_pv(screenGroup, SCREEN_PROPERTY_KEYBOARD_FOCUS, + screen_set_group_property_pv(screenGroup, SCREEN_PROPERTY_FOCUS, reinterpret_cast(&newFocusWindow)); } } From 597d625c2cd87fec870a23ea3c57eb0a106c993e Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 15 Sep 2016 09:11:19 -0700 Subject: [PATCH 45/87] Disable forcing of -fomit-frame-pointer with ICC qlogging.cpp(1226): error #3175: unrecognized gcc optimization level __attribute__((optimize("omit-frame-pointer"))) ^ Change-Id: I33dc971f005a4848bb8ffffd14748b100dcefa95 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/global/qlogging.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp index 49a8aa0df1b..5842b26ecbc 100644 --- a/src/corelib/global/qlogging.cpp +++ b/src/corelib/global/qlogging.cpp @@ -1197,7 +1197,8 @@ void QMessagePattern::setPattern(const QString &pattern) #if defined(QLOGGING_HAVE_BACKTRACE) && !defined(QT_BOOTSTRAPPED) // make sure the function has "Message" in the name so the function is removed -#if (defined(Q_CC_GNU) && defined(QT_COMPILER_SUPPORTS_SIMD_ALWAYS)) || QT_HAS_ATTRIBUTE(optimize) +#if ((defined(Q_CC_GNU) && defined(QT_COMPILER_SUPPORTS_SIMD_ALWAYS)) || QT_HAS_ATTRIBUTE(optimize)) \ + && !defined(Q_CC_INTEL) // force skipping the frame pointer, to save the backtrace() function some work __attribute__((optimize("omit-frame-pointer"))) #endif From 734da261a8283701a25c1690c5270ba70c8d0a37 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Thu, 8 Sep 2016 12:45:20 +0300 Subject: [PATCH 46/87] Android: Don't hang when resuming the application If the main thread is blocked updateApplicationState will hang. It happens when we're using functions like runOnAndroidThreadSync or requestPermissionsSync. Change-Id: Ic1135c5630b48cf1076ef5cbc133933fce439bfb Reviewed-by: Alex Blasche --- src/plugins/platforms/android/androidjnimain.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp index 677a2e2626b..c79198d7fe5 100644 --- a/src/plugins/platforms/android/androidjnimain.cpp +++ b/src/plugins/platforms/android/androidjnimain.cpp @@ -672,11 +672,6 @@ static void updateApplicationState(JNIEnv */*env*/, jobject /*thiz*/, jint state QAndroidEventDispatcherStopper::instance()->goingToStop(true); QCoreApplication::processEvents(); QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationState(state)); - { - AndroidDeadlockProtector protector; - if (protector.acquire()) - QWindowSystemInterface::flushWindowSystemEvents(); - } if (state == Qt::ApplicationSuspended) QAndroidEventDispatcherStopper::instance()->stopAll(); } else { From 76adb6c29f9284a3d7cceb8fb09c3bb7c4cd5e1b Mon Sep 17 00:00:00 2001 From: Albert Astals Cid Date: Thu, 21 Apr 2016 01:39:27 +0200 Subject: [PATCH 47/87] xcb: Use the state of the key event to process it Instead of the global state Task-number: QTBUG-48795 Change-Id: Ic2c545718adb68df41730e5a3bf25adb374ffce3 Reviewed-by: Frederik Gladhorn Reviewed-by: Edward Welbourne Reviewed-by: Gatis Paeglis --- src/plugins/platforms/xcb/qxcbkeyboard.cpp | 72 +++++++++++++--------- src/plugins/platforms/xcb/qxcbkeyboard.h | 2 + 2 files changed, 46 insertions(+), 28 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp index 28de86b8ba2..e0fcc01fb41 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp +++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp @@ -742,8 +742,7 @@ void QXcbKeyboard::updateKeymap() // update xkb state object xkb_state_unref(xkb_state); xkb_state = new_state; - if (!connection()->hasXKB()) - updateXKBMods(); + updateXKBMods(); checkForLatinLayout(); } @@ -768,32 +767,37 @@ void QXcbKeyboard::updateXKBState(xcb_xkb_state_notify_event_t *state) } #endif +void QXcbKeyboard::updateXKBStateFromState(struct xkb_state *kb_state, quint16 state) +{ + const quint32 modsDepressed = xkb_state_serialize_mods(kb_state, XKB_STATE_MODS_DEPRESSED); + const quint32 modsLatched = xkb_state_serialize_mods(kb_state, XKB_STATE_MODS_LATCHED); + const quint32 modsLocked = xkb_state_serialize_mods(kb_state, XKB_STATE_MODS_LOCKED); + const quint32 xkbMask = xkbModMask(state); + + const quint32 latched = modsLatched & xkbMask; + const quint32 locked = modsLocked & xkbMask; + quint32 depressed = modsDepressed & xkbMask; + // set modifiers in depressed if they don't appear in any of the final masks + depressed |= ~(depressed | latched | locked) & xkbMask; + + const xkb_state_component newState + = xkb_state_update_mask(kb_state, + depressed, + latched, + locked, + 0, + 0, + (state >> 13) & 3); // bits 13 and 14 report the state keyboard group + + if ((newState & XKB_STATE_LAYOUT_EFFECTIVE) == XKB_STATE_LAYOUT_EFFECTIVE) { + //qWarning("TODO: Support KeyboardLayoutChange on QPA (QTBUG-27681)"); + } +} + void QXcbKeyboard::updateXKBStateFromCore(quint16 state) { if (m_config && !connection()->hasXKB()) { - const quint32 modsDepressed = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_DEPRESSED); - const quint32 modsLatched = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_LATCHED); - const quint32 modsLocked = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_LOCKED); - const quint32 xkbMask = xkbModMask(state); - - const quint32 latched = modsLatched & xkbMask; - const quint32 locked = modsLocked & xkbMask; - quint32 depressed = modsDepressed & xkbMask; - // set modifiers in depressed if they don't appear in any of the final masks - depressed |= ~(depressed | latched | locked) & xkbMask; - - const xkb_state_component newState - = xkb_state_update_mask(xkb_state, - depressed, - latched, - locked, - 0, - 0, - (state >> 13) & 3); // bits 13 and 14 report the state keyboard group - - if ((newState & XKB_STATE_LAYOUT_EFFECTIVE) == XKB_STATE_LAYOUT_EFFECTIVE) { - //qWarning("TODO: Support KeyboardLayoutChange on QPA (QTBUG-27681)"); - } + updateXKBStateFromState(xkb_state, state); } } @@ -1455,7 +1459,16 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type, if (type == QEvent::KeyPress) targetWindow->updateNetWmUserTime(time); - xcb_keysym_t sym = xkb_state_key_get_one_sym(xkb_state, code); + // Have a temporary keyboard state filled in from state + // this way we allow for synthetic events to have different state + // from the current state i.e. you can have Alt+Ctrl pressed + // and receive a synthetic key event that has neither Alt nor Ctrl pressed + struct xkb_state *kb_state = xkb_state_new(xkb_keymap); + if (!kb_state) + return; + updateXKBStateFromState(kb_state, state); + + xcb_keysym_t sym = xkb_state_key_get_one_sym(kb_state, code); QPlatformInputContext *inputContext = QGuiApplicationPrivate::platformIntegration()->inputContext(); QMetaMethod method; @@ -1474,11 +1487,13 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type, Q_ARG(uint, code), Q_ARG(uint, state), Q_ARG(bool, type == QEvent::KeyPress)); - if (retval) + if (retval) { + xkb_state_unref(kb_state); return; + } } - QString string = lookupString(xkb_state, code); + QString string = lookupString(kb_state, code); // Ιf control modifier is set we should prefer latin character, this is // used for standard shortcuts in checks like "key == QKeySequence::Copy", @@ -1547,6 +1562,7 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type, QWindowSystemInterface::handleExtendedKeyEvent(window, time, QEvent::KeyPress, qtcode, modifiers, code, sym, state, string, isAutoRepeat); } + xkb_state_unref(kb_state); } QString QXcbKeyboard::lookupString(struct xkb_state *state, xcb_keycode_t code) const diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.h b/src/plugins/platforms/xcb/qxcbkeyboard.h index 457a27affb1..dc27511b56e 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.h +++ b/src/plugins/platforms/xcb/qxcbkeyboard.h @@ -98,6 +98,8 @@ protected: void checkForLatinLayout(); private: + void updateXKBStateFromState(struct xkb_state *kb_state, quint16 state); + bool m_config; xcb_keycode_t m_autorepeat_code; From 8d64d1e0c3f7ebcee859e8b5f40aa27a8df86351 Mon Sep 17 00:00:00 2001 From: Albert Astals Cid Date: Tue, 31 May 2016 01:13:03 +0200 Subject: [PATCH 48/87] xcb: Do not eat events with different keyboard state Change-Id: Iac8dc7b369eb7c2fbe0cf27baa34a40278088219 Reviewed-by: Frederik Gladhorn Reviewed-by: Gatis Paeglis --- src/plugins/platforms/xcb/qxcbkeyboard.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp index 811ef4251a1..bb7d5c714a1 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp +++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp @@ -1393,10 +1393,11 @@ void QXcbKeyboard::resolveMaskConflicts() class KeyChecker { public: - KeyChecker(xcb_window_t window, xcb_keycode_t code, xcb_timestamp_t time) + KeyChecker(xcb_window_t window, xcb_keycode_t code, xcb_timestamp_t time, quint16 state) : m_window(window) , m_code(code) , m_time(time) + , m_state(state) , m_error(false) , m_release(true) { @@ -1413,7 +1414,7 @@ public: xcb_key_press_event_t *event = (xcb_key_press_event_t *)ev; - if (event->event != m_window || event->detail != m_code) { + if (event->event != m_window || event->detail != m_code || event->state != m_state) { m_error = true; return false; } @@ -1441,6 +1442,7 @@ private: xcb_window_t m_window; xcb_keycode_t m_code; xcb_timestamp_t m_time; + quint16 m_state; bool m_error; bool m_release; @@ -1505,7 +1507,7 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type, } } else { // look ahead for auto-repeat - KeyChecker checker(source->xcb_window(), code, time); + KeyChecker checker(source->xcb_window(), code, time, state); xcb_generic_event_t *event = connection()->checkEvent(checker); if (event) { isAutoRepeat = true; From 29d64bc8e06d6809ac0c68b7b5459a8a51667769 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 15 Sep 2016 17:31:25 +0200 Subject: [PATCH 49/87] QEvdevKeyboardHandler: use RAII in create()/ctor Coverity somewhat rightfully complained that the FD may be leaked in certain cases, e.g. when the new-expression throws. Yes, the plugin is compiled with exceptions disabled, but the code is still a bug waiting to happen, because it's too easy to just add an early return to the function and leak the FD that way. Fix by writing a small RAII class for FDs (can't use QSharedPointer, since it's not a pointer we're dealing with). It's quite generically named, in anticipation that it might come in handy elsewhere, too. Coverity-Id: 89046 Change-Id: I83d1ed3f11219065d2248c129ed191a651f617c7 Reviewed-by: Thiago Macieira --- .../evdevkeyboard/qevdevkeyboardhandler.cpp | 34 ++++++++++--------- .../evdevkeyboard/qevdevkeyboardhandler_p.h | 17 ++++++++-- 2 files changed, 33 insertions(+), 18 deletions(-) diff --git a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp index 089cc130327..3363859dae8 100644 --- a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp +++ b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp @@ -52,8 +52,15 @@ Q_LOGGING_CATEGORY(qLcEvdevKeyMap, "qt.qpa.input.keymap") // simple builtin US keymap #include "qevdevkeyboard_defaultmap_p.h" -QEvdevKeyboardHandler::QEvdevKeyboardHandler(const QString &device, int fd, bool disableZap, bool enableCompose, const QString &keymapFile) - : m_device(device), m_fd(fd), m_notify(Q_NULLPTR), +void QFdContainer::reset() Q_DECL_NOTHROW +{ + if (m_fd >= 0) + qt_safe_close(m_fd); + m_fd = -1; +} + +QEvdevKeyboardHandler::QEvdevKeyboardHandler(const QString &device, QFdContainer &fd, bool disableZap, bool enableCompose, const QString &keymapFile) + : m_device(device), m_fd(fd.release()), m_notify(Q_NULLPTR), m_modifiers(0), m_composing(0), m_dead_unicode(0xffff), m_no_zap(disableZap), m_do_compose(enableCompose), m_keymap(0), m_keymap_size(0), m_keycompose(0), m_keycompose_size(0) @@ -68,16 +75,13 @@ QEvdevKeyboardHandler::QEvdevKeyboardHandler(const QString &device, int fd, bool unloadKeymap(); // socket notifier for events on the keyboard device - m_notify = new QSocketNotifier(m_fd, QSocketNotifier::Read, this); + m_notify = new QSocketNotifier(m_fd.get(), QSocketNotifier::Read, this); connect(m_notify, SIGNAL(activated(int)), this, SLOT(readKeycode())); } QEvdevKeyboardHandler::~QEvdevKeyboardHandler() { unloadKeymap(); - - if (m_fd >= 0) - qt_safe_close(m_fd); } QEvdevKeyboardHandler *QEvdevKeyboardHandler::create(const QString &device, @@ -111,13 +115,12 @@ QEvdevKeyboardHandler *QEvdevKeyboardHandler::create(const QString &device, qCDebug(qLcEvdevKey) << "Opening keyboard at" << device; - int fd; - fd = qt_safe_open(device.toLocal8Bit().constData(), O_RDONLY | O_NDELAY, 0); - if (fd >= 0) { - ::ioctl(fd, EVIOCGRAB, grab); + QFdContainer fd(qt_safe_open(device.toLocal8Bit().constData(), O_RDONLY | O_NDELAY, 0)); + if (fd.get() >= 0) { + ::ioctl(fd.get(), EVIOCGRAB, grab); if (repeatDelay > 0 && repeatRate > 0) { int kbdrep[2] = { repeatDelay, repeatRate }; - ::ioctl(fd, EVIOCSREP, kbdrep); + ::ioctl(fd.get(), EVIOCSREP, kbdrep); } return new QEvdevKeyboardHandler(device, fd, disableZap, enableCompose, keymapFile); @@ -137,7 +140,7 @@ void QEvdevKeyboardHandler::switchLed(int led, bool state) led_ie.code = led; led_ie.value = state; - qt_safe_write(m_fd, &led_ie, sizeof(led_ie)); + qt_safe_write(m_fd.get(), &led_ie, sizeof(led_ie)); } void QEvdevKeyboardHandler::readKeycode() @@ -146,7 +149,7 @@ void QEvdevKeyboardHandler::readKeycode() int n = 0; forever { - int result = qt_safe_read(m_fd, reinterpret_cast(buffer) + n, sizeof(buffer) - n); + int result = qt_safe_read(m_fd.get(), reinterpret_cast(buffer) + n, sizeof(buffer) - n); if (result == 0) { qWarning("evdevkeyboard: Got EOF from the input device"); @@ -159,8 +162,7 @@ void QEvdevKeyboardHandler::readKeycode() if (errno == ENODEV) { delete m_notify; m_notify = Q_NULLPTR; - qt_safe_close(m_fd); - m_fd = -1; + m_fd.reset(); } return; } @@ -471,7 +473,7 @@ void QEvdevKeyboardHandler::unloadKeymap() //Set locks according to keyboard leds quint16 ledbits[1]; memset(ledbits, 0, sizeof(ledbits)); - if (::ioctl(m_fd, EVIOCGLED(sizeof(ledbits)), ledbits) < 0) { + if (::ioctl(m_fd.get(), EVIOCGLED(sizeof(ledbits)), ledbits) < 0) { qWarning("evdevkeyboard: Failed to query led states"); switchLed(LED_NUML,false); switchLed(LED_CAPSL, false); diff --git a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler_p.h b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler_p.h index 84c251c3c2b..b08f30b6eec 100644 --- a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler_p.h +++ b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler_p.h @@ -123,12 +123,25 @@ inline QDataStream &operator<<(QDataStream &ds, const QEvdevKeyboardMap::Composi return ds << c.first << c.second << c.result; } +class QFdContainer +{ + int m_fd; + Q_DISABLE_COPY(QFdContainer); +public: + explicit QFdContainer(int fd = -1) Q_DECL_NOTHROW : m_fd(fd) {} + ~QFdContainer() { reset(); } + + int get() const Q_DECL_NOTHROW { return m_fd; } + + int release() Q_DECL_NOTHROW { int result = m_fd; m_fd = -1; return result; } + void reset() Q_DECL_NOTHROW; +}; class QEvdevKeyboardHandler : public QObject { Q_OBJECT public: - QEvdevKeyboardHandler(const QString &device, int fd, bool disableZap, bool enableCompose, const QString &keymapFile); + QEvdevKeyboardHandler(const QString &device, QFdContainer &fd, bool disableZap, bool enableCompose, const QString &keymapFile); ~QEvdevKeyboardHandler(); enum KeycodeAction { @@ -181,7 +194,7 @@ private: void switchLed(int, bool); QString m_device; - int m_fd; + QFdContainer m_fd; QSocketNotifier *m_notify; // keymap handling From 8082c0dc81b50c44a0cf1984cb2c484b007c64a4 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sun, 18 Sep 2016 16:44:19 +0200 Subject: [PATCH 50/87] QBrush: Fix UB (non-virtual dtor) in QBrush::detach() As the d-pointer, QBrush uses a QScopedPointer with a custom deleter that checks for QBrushData::style and casts the QBrushData pointer down to corresponding subclasses before calling delete on them. In QBrush::detach(), however, any of the three brush data classes were held in a QScopedPointer _without_ the custom deleter, invoking UB when that scoped pointer would ever get to be the one that deleted the payload instead of handing it over to the objects d-pointer. Found by making dtors protected following a Coverity report wrongly marked as 'dismissed' (these static checks are not included in this patch, since they are binary-incompatible), to find out where Coverity could possibly see a problem. Also replace the d.reset(x.take()) that allowed this mismatch to compile with d.swap(x), which nicely ensures that x and d are of the same type. Coverity-Id: 11772 Change-Id: I85e2c205df9291bd7508b6c90f7b03fbe8c3bcd2 Reviewed-by: Thiago Macieira --- src/gui/painting/qbrush.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/gui/painting/qbrush.cpp b/src/gui/painting/qbrush.cpp index 9e039b7ae44..ee42f2b5111 100644 --- a/src/gui/painting/qbrush.cpp +++ b/src/gui/painting/qbrush.cpp @@ -579,7 +579,7 @@ void QBrush::detach(Qt::BrushStyle newStyle) if (newStyle == d->style && d->ref.load() == 1) return; - QScopedPointer x; + QScopedPointer x; switch(newStyle) { case Qt::TexturePattern: { QTexturedBrushData *tbd = new QTexturedBrushData; @@ -595,28 +595,30 @@ void QBrush::detach(Qt::BrushStyle newStyle) } case Qt::LinearGradientPattern: case Qt::RadialGradientPattern: - case Qt::ConicalGradientPattern: - x.reset(new QGradientBrushData); + case Qt::ConicalGradientPattern: { + QGradientBrushData *gbd = new QGradientBrushData; switch (d->style) { case Qt::LinearGradientPattern: case Qt::RadialGradientPattern: case Qt::ConicalGradientPattern: - static_cast(x.data())->gradient = + gbd->gradient = static_cast(d.data())->gradient; break; default: break; } + x.reset(gbd); break; + } default: x.reset(new QBrushData); break; } - x->ref.store(1); + x->ref.store(1); // must be first lest the QBrushDataPointerDeleter turns into a no-op x->style = newStyle; x->color = d->color; x->transform = d->transform; - d.reset(x.take()); + d.swap(x); } From bcbc8120b30a3d94d6a131ad936a8270657ffd96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 25 Aug 2016 13:02:47 +0200 Subject: [PATCH 51/87] multiwindow: Use showNormal() instead of show() to ensure normal geometry Change-Id: Ice607f536a620da5a70f2ba066f4983bb78c6288 Reviewed-by: Simon Hausmann --- tests/manual/qopenglwindow/multiwindow/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/manual/qopenglwindow/multiwindow/main.cpp b/tests/manual/qopenglwindow/multiwindow/main.cpp index caa15078d55..66ebb73c56f 100644 --- a/tests/manual/qopenglwindow/multiwindow/main.cpp +++ b/tests/manual/qopenglwindow/multiwindow/main.cpp @@ -187,7 +187,7 @@ int main(int argc, char **argv) QPoint position = availableGeometry.topLeft(); position += QPoint(col * windowWidth, row * windowHeight); w->setFramePosition(position); - w->show(); + w->showNormal(); } int r = app.exec(); From 6ce96fdbf59138bebadbd8157d8285327a1a3796 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 25 Aug 2016 13:09:27 +0200 Subject: [PATCH 52/87] multiwindow: React to mouse press to allow debugging UI responsiveness The animated FPS counter should be enough to observe smooth animations, so we use the color of the window to visualize frame latency. Change-Id: I1171a1c4bdc261ca8655771290c6735357821781 Reviewed-by: Simon Hausmann --- .../manual/qopenglwindow/multiwindow/main.cpp | 53 +++++++------------ 1 file changed, 20 insertions(+), 33 deletions(-) diff --git a/tests/manual/qopenglwindow/multiwindow/main.cpp b/tests/manual/qopenglwindow/multiwindow/main.cpp index 66ebb73c56f..31688d717e9 100644 --- a/tests/manual/qopenglwindow/multiwindow/main.cpp +++ b/tests/manual/qopenglwindow/multiwindow/main.cpp @@ -31,14 +31,7 @@ ** ****************************************************************************/ -#include -#include -#include -#include -#include -#include -#include -#include +#include const char applicationDescription[] = "\n\ This application opens multiple windows and continuously schedules updates for\n\ @@ -67,40 +60,26 @@ class Window : public QOpenGLWindow { Q_OBJECT public: - Window(int n) : idx(n) { - r = g = b = fps = 0; - y = 0; + Window(int index) : windowNumber(index + 1), y(0), fps(0) { + + color = QColor::fromHsl((index * 30) % 360, 255, 127).toRgb(); + resize(200, 200); + setObjectName(QString("Window %1").arg(windowNumber)); + connect(this, SIGNAL(frameSwapped()), SLOT(frameSwapped())); fpsTimer.start(); } void paintGL() { QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); - f->glClearColor(r, g, b, 1); + f->glClearColor(color.redF(), color.greenF(), color.blueF(), 1); f->glClear(GL_COLOR_BUFFER_BIT); - switch (idx % 3) { - case 0: - r += 0.005f; - break; - case 1: - g += 0.005f; - break; - case 2: - b += 0.005f; - break; - } - if (r > 1) - r = 0; - if (g > 1) - g = 0; - if (b > 1) - b = 0; QPainter p(this); p.setPen(Qt::white); - p.drawText(QPoint(20, y), QString(QLatin1String("Window %1 (%2 FPS)")).arg(idx).arg(fps)); + p.drawText(QPoint(20, y), QString(QLatin1String("Window %1 (%2 FPS)")).arg(windowNumber).arg(fps)); y += 1; if (y > height() - 20) y = 20; @@ -118,9 +97,17 @@ public slots: } } +protected: + void mousePressEvent(QMouseEvent *event) { + qDebug() << this << event; + color.setHsl((color.hue() + 90) % 360, color.saturation(), color.lightness()); + color = color.toRgb(); + } + private: - int idx; - GLfloat r, g, b; + int windowNumber; + QColor color; + int y; int framesSwapped; @@ -163,7 +150,7 @@ int main(int argc, char **argv) int numberOfWindows = qMax(parser.value(numWindowsOption).toInt(), 1); QList windows; for (int i = 0; i < numberOfWindows; ++i) { - Window *w = new Window(i + 1); + Window *w = new Window(i); windows << w; if (i == 0 && parser.isSet(vsyncOneOption)) { From 44fec65624d3569144e40b394af499172c81a7a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 31 Aug 2016 19:42:31 +0200 Subject: [PATCH 53/87] Update swap interval of QCocoaGLContext after creation QSurfaceFormat is recreated from scratch, and by not reading back the swap interval the QCocoaGLContext seemed to be vsynced even if it actually was not. Change-Id: I72ddaae9a4c695fe4c74d7b4b70ca9db84bcc084 Reviewed-by: Laszlo Agocs --- src/plugins/platforms/cocoa/qcocoaglcontext.mm | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.mm b/src/plugins/platforms/cocoa/qcocoaglcontext.mm index b77ca071418..4ae81ef3ab9 100644 --- a/src/plugins/platforms/cocoa/qcocoaglcontext.mm +++ b/src/plugins/platforms/cocoa/qcocoaglcontext.mm @@ -323,6 +323,11 @@ void QCocoaGLContext::updateSurfaceFormat() [pixelFormat release]; + GLint swapInterval = -1; + [m_context getValues:&swapInterval forParameter:NSOpenGLCPSwapInterval]; + if (swapInterval >= 0) + m_format.setSwapInterval(swapInterval); + // Restore the original context CGLSetCurrentContext(oldContext); } From 880beb121e76b60cdfbd59d6a04fd600532c72bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 31 Aug 2016 18:21:18 +0200 Subject: [PATCH 54/87] multiwindow: Call update() after swap Change-Id: Ic2c26339bce9fe92b2ccc730c72f53ce94397b78 Reviewed-by: Simon Hausmann --- tests/manual/qopenglwindow/multiwindow/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/manual/qopenglwindow/multiwindow/main.cpp b/tests/manual/qopenglwindow/multiwindow/main.cpp index 31688d717e9..17442dbae54 100644 --- a/tests/manual/qopenglwindow/multiwindow/main.cpp +++ b/tests/manual/qopenglwindow/multiwindow/main.cpp @@ -83,8 +83,6 @@ public: y += 1; if (y > height() - 20) y = 20; - - update(); } public slots: @@ -95,6 +93,8 @@ public slots: framesSwapped = 0; fpsTimer.restart(); } + + update(); } protected: From efdecff085d6e9d8c738bd681757c8cc18a3a451 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 31 Aug 2016 18:15:52 +0200 Subject: [PATCH 55/87] multiwindow: Replace per window fps timers with unified approach The FPS is now calculated and output on the command line in a single place. The animated fps counter has been replaced with a vertical line which should make it easier to observe tearing issues when vsync is disabled. Change-Id: Id356fc1958c048d85aba48edfed59124454038d4 Reviewed-by: Simon Hausmann --- .../manual/qopenglwindow/multiwindow/main.cpp | 64 +++++++++++++------ 1 file changed, 46 insertions(+), 18 deletions(-) diff --git a/tests/manual/qopenglwindow/multiwindow/main.cpp b/tests/manual/qopenglwindow/multiwindow/main.cpp index 17442dbae54..8b17226366a 100644 --- a/tests/manual/qopenglwindow/multiwindow/main.cpp +++ b/tests/manual/qopenglwindow/multiwindow/main.cpp @@ -60,7 +60,7 @@ class Window : public QOpenGLWindow { Q_OBJECT public: - Window(int index) : windowNumber(index + 1), y(0), fps(0) { + Window(int index) : windowNumber(index + 1), x(0), framesSwapped(0) { color = QColor::fromHsl((index * 30) % 360, 255, 127).toRgb(); @@ -69,7 +69,6 @@ public: setObjectName(QString("Window %1").arg(windowNumber)); connect(this, SIGNAL(frameSwapped()), SLOT(frameSwapped())); - fpsTimer.start(); } void paintGL() { @@ -77,23 +76,14 @@ public: f->glClearColor(color.redF(), color.greenF(), color.blueF(), 1); f->glClear(GL_COLOR_BUFFER_BIT); - QPainter p(this); - p.setPen(Qt::white); - p.drawText(QPoint(20, y), QString(QLatin1String("Window %1 (%2 FPS)")).arg(windowNumber).arg(fps)); - y += 1; - if (y > height() - 20) - y = 20; + QPainter painter(this); + painter.drawLine(x, 0, x, height()); + x = ++x % width(); } public slots: void frameSwapped() { ++framesSwapped; - if (fpsTimer.elapsed() > 1000) { - fps = qRound(framesSwapped * (1000.0 / fpsTimer.elapsed())); - framesSwapped = 0; - fpsTimer.restart(); - } - update(); } @@ -107,14 +97,46 @@ protected: private: int windowNumber; QColor color; - - int y; + int x; int framesSwapped; - QElapsedTimer fpsTimer; - int fps; + friend void printFps(); }; +static const qreal kFpsInterval = 500; + +void printFps() +{ + static QElapsedTimer timer; + if (!timer.isValid()) { + timer.start(); + return; + } + + const qreal frameFactor = (kFpsInterval / timer.elapsed()) * (1000.0 / kFpsInterval); + + QDebug output = qDebug().nospace(); + + qreal averageFps = 0; + const QWindowList windows = QGuiApplication::topLevelWindows(); + for (int i = 0; i < windows.size(); ++i) { + Window *w = qobject_cast(windows.at(i)); + Q_ASSERT(w); + + int fps = qRound(w->framesSwapped * frameFactor); + output << (i + 1) << "=" << fps << ", "; + + averageFps += fps; + w->framesSwapped = 0; + } + averageFps = qRound(averageFps / windows.size()); + qreal msPerFrame = 1000.0 / averageFps; + + output << "avg=" << averageFps << ", ms=" << msPerFrame; + + timer.restart(); +} + int main(int argc, char **argv) { QGuiApplication app(argc, argv); @@ -177,6 +199,12 @@ int main(int argc, char **argv) w->showNormal(); } + QTimer fpsTimer; + fpsTimer.setInterval(kFpsInterval); + fpsTimer.setTimerType(Qt::PreciseTimer); + QObject::connect(&fpsTimer, &QTimer::timeout, &printFps); + fpsTimer.start(); + int r = app.exec(); qDeleteAll(windows); return r; From fecee98836842af1693696c547405af3f740e0d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 25 Aug 2016 15:04:54 +0200 Subject: [PATCH 56/87] multiwindow: Base vsync debug output on actual surface format Allows us to detect cases where the requested vsync combination was not possible to fulfill. Change-Id: Ie8f3665129f7a1ab7fcefb94b2298d54520b753a Reviewed-by: Simon Hausmann --- .../manual/qopenglwindow/multiwindow/main.cpp | 30 +++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/tests/manual/qopenglwindow/multiwindow/main.cpp b/tests/manual/qopenglwindow/multiwindow/main.cpp index 8b17226366a..89a94f3b3eb 100644 --- a/tests/manual/qopenglwindow/multiwindow/main.cpp +++ b/tests/manual/qopenglwindow/multiwindow/main.cpp @@ -88,6 +88,18 @@ public slots: } protected: + void exposeEvent(QExposeEvent *event) { + if (!isExposed()) + return; + + QSurfaceFormat format = context()->format(); + qDebug() << this << format.swapBehavior() << "with Vsync =" << (format.swapInterval() ? "ON" : "OFF"); + if (format.swapInterval() != requestedFormat().swapInterval()) + qWarning() << "WARNING: Did not get requested swap interval of" << requestedFormat().swapInterval() << "for" << this; + + QOpenGLWindow::exposeEvent(event); + } + void mousePressEvent(QMouseEvent *event) { qDebug() << this << event; color.setHsl((color.hue() + 90) % 360, color.saturation(), color.lightness()); @@ -158,14 +170,9 @@ int main(int argc, char **argv) parser.process(app); - QSurfaceFormat fmt; - if (parser.isSet(noVsyncOption)) { - qDebug("swap interval 0 (no throttling)"); - fmt.setSwapInterval(0); - } else { - qDebug("swap interval 1 (sync to vblank)"); - } - QSurfaceFormat::setDefaultFormat(fmt); + QSurfaceFormat defaultSurfaceFormat; + defaultSurfaceFormat.setSwapInterval(parser.isSet(noVsyncOption) ? 0 : 1); + QSurfaceFormat::setDefaultFormat(defaultSurfaceFormat); QRect availableGeometry = app.primaryScreen()->availableGeometry(); @@ -176,12 +183,11 @@ int main(int argc, char **argv) windows << w; if (i == 0 && parser.isSet(vsyncOneOption)) { - qDebug("swap interval 1 for first window only"); - QSurfaceFormat vsyncedSurfaceFormat = fmt; + QSurfaceFormat vsyncedSurfaceFormat = defaultSurfaceFormat; vsyncedSurfaceFormat.setSwapInterval(1); w->setFormat(vsyncedSurfaceFormat); - fmt.setSwapInterval(0); - QSurfaceFormat::setDefaultFormat(fmt); + defaultSurfaceFormat.setSwapInterval(0); + QSurfaceFormat::setDefaultFormat(defaultSurfaceFormat); } static int windowWidth = w->width() + 20; From e30d0e462f32d787a9d72acfef7026fb5019bb75 Mon Sep 17 00:00:00 2001 From: Frederik Schwarzer Date: Wed, 17 Aug 2016 13:27:03 +0200 Subject: [PATCH 57/87] QAbstractProxyModel: fix sentence structure in apidoc Change-Id: Ib3371549ecb80da326260b1df431f20e7a04f07e Reviewed-by: Giuseppe D'Angelo --- src/corelib/itemmodels/qabstractproxymodel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/itemmodels/qabstractproxymodel.cpp b/src/corelib/itemmodels/qabstractproxymodel.cpp index dbbbbb8ff47..c33b0a56b8c 100644 --- a/src/corelib/itemmodels/qabstractproxymodel.cpp +++ b/src/corelib/itemmodels/qabstractproxymodel.cpp @@ -77,7 +77,7 @@ QT_BEGIN_NAMESPACE /*! \property QAbstractProxyModel::sourceModel - \brief the source model this proxy model. + \brief the source model of this proxy model. */ //detects the deletion of the source model From d3389a6d460a7d51a9672247366c60504f427b29 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 6 Sep 2016 14:36:20 +0200 Subject: [PATCH 58/87] iOS: let quiview conform to API signature changes in iOS 10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In the iOS 10 SDK, method signatures has been annotated with NS_ASSUME_NONNULL macros and 'nullable' keywords. This means that certain methods should not be called with argumens that can be null, or in this case, set to 0 explicitly. The result will be compiler warnings. This patch will rewrite the explicit call we do to touchesCancelled so that we send an empty set instead of 0. Change-Id: I50aa80b91312397d17e0e380815adff87cee852b Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.mm | 2 +- src/plugins/platforms/ios/quiview.mm | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index a1576eba8ef..68afed20341 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -85,7 +85,7 @@ QIOSWindow::~QIOSWindow() // practice this doesn't seem to happen when removing the view from its superview. To ensure that // Qt's internal state for touch and mouse handling is kept consistent, we therefor have to force // cancellation of all touch events. - [m_view touchesCancelled:0 withEvent:0]; + [m_view touchesCancelled:[NSSet set] withEvent:0]; clearAccessibleCache(); m_view->m_qioswindow = 0; diff --git a/src/plugins/platforms/ios/quiview.mm b/src/plugins/platforms/ios/quiview.mm index 4dd43be465f..dce30988461 100644 --- a/src/plugins/platforms/ios/quiview.mm +++ b/src/plugins/platforms/ios/quiview.mm @@ -417,7 +417,8 @@ // We do this by assuming that there are no cases where a // sub-set of the active touch events are intentionally cancelled. - if (touches && (static_cast([touches count]) != m_activeTouches.count())) + NSInteger count = static_cast([touches count]); + if (count != 0 && count != m_activeTouches.count()) qWarning("Subset of active touches cancelled by UIKit"); m_activeTouches.clear(); From e32ecdb28079a60f86aca0eee648c11f7993b460 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 6 Sep 2016 11:00:21 +0200 Subject: [PATCH 59/87] iOS: explicit synthesize properties as readwrite MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The synthesized properties were defined as (read only) methods in the UIViewController API in iOS9, and we extended them into readwrite properties in our own sub class to enable some local bookkeeping in addition to normal overriding. But in iOS10, Apple has changed the methods into being readonly properties instead. The difference then is that automatic property synthesizing will ignore our local readwrite declarations, and use the declarations in the super class instead. And this will lead to a runtime crash on iOS10 since no setter methods are generated. This patch will instead explicit synthesize the affected properties to ensure that both getters and setters will be generated. Change-Id: Iac330e991b8a0fe335e383e1f7d9ff30c0ce1559 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosviewcontroller.mm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm index ed76161b876..a4460a6737f 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.mm +++ b/src/plugins/platforms/ios/qiosviewcontroller.mm @@ -222,6 +222,10 @@ @implementation QIOSViewController +@synthesize prefersStatusBarHidden; +@synthesize preferredStatusBarUpdateAnimation; +@synthesize preferredStatusBarStyle; + - (id)initWithQIOSScreen:(QIOSScreen *)screen { if (self = [self init]) { From 8347b54b9738e29807c3c7913bda8fe7cf3f7dba Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 21 Jun 2016 13:19:02 +0200 Subject: [PATCH 60/87] iOS: open menu on popup regardless of visibility MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It should be possible to show a menu by calling showPopup, even if visible is set to false. After all, it's only logical that visibility is false before showing it. And whether or not the menu is enabled should not matter as well. Change-Id: I9a2b453c8c6e88c47812c652d99e4b4a9c7524a7 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosmenu.mm | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/ios/qiosmenu.mm b/src/plugins/platforms/ios/qiosmenu.mm index 612f8c43a27..3e97b1161c7 100644 --- a/src/plugins/platforms/ios/qiosmenu.mm +++ b/src/plugins/platforms/ios/qiosmenu.mm @@ -344,7 +344,7 @@ QIOSMenu::QIOSMenu() : QPlatformMenu() , m_tag(0) , m_enabled(true) - , m_visible(true) + , m_visible(false) , m_text(QString()) , m_menuType(DefaultMenu) , m_effectiveMenuType(DefaultMenu) @@ -437,7 +437,7 @@ void QIOSMenu::handleItemSelected(QIOSMenuItem *menuItem) void QIOSMenu::showPopup(const QWindow *parentWindow, const QRect &targetRect, const QPlatformMenuItem *item) { - if (m_currentMenu == this || !m_visible || !m_enabled || !parentWindow) + if (m_currentMenu == this || !parentWindow) return; emit aboutToShow(); @@ -464,6 +464,8 @@ void QIOSMenu::showPopup(const QWindow *parentWindow, const QRect &targetRect, c toggleShowUsingUIPickerView(true); break; } + + m_visible = true; } void QIOSMenu::dismiss() @@ -485,6 +487,7 @@ void QIOSMenu::dismiss() } m_currentMenu = 0; + m_visible = false; } void QIOSMenu::toggleShowUsingUIMenuController(bool show) From 9f2c260f881b384ae719c60ea9833feb42251058 Mon Sep 17 00:00:00 2001 From: Samuel Gaist Date: Sun, 27 Sep 2015 01:26:28 +0200 Subject: [PATCH 61/87] Add missing test for QReguarExpression for QTextDocument::findMultiple Change-Id: Ia9b3eb21a178da4ae2844dba37b7e1cc669d6b50 Reviewed-by: Simon Hausmann --- .../text/qtextdocument/tst_qtextdocument.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp b/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp index bb20d99e307..3c9de9d211c 100644 --- a/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp +++ b/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp @@ -468,6 +468,24 @@ void tst_QTextDocument::findMultiple() cursor = doc->find(expr, cursor); QCOMPARE(cursor.selectionStart(), text.lastIndexOf("bar")); QCOMPARE(cursor.selectionEnd(), cursor.selectionStart() + 3); + + QRegularExpression regularExpression("bar"); + + cursor.movePosition(QTextCursor::End); + cursor = doc->find(regularExpression, cursor, QTextDocument::FindBackward); + QCOMPARE(cursor.selectionStart(), text.lastIndexOf("bar")); + QCOMPARE(cursor.selectionEnd(), cursor.selectionStart() + 3); + cursor = doc->find(regularExpression, cursor, QTextDocument::FindBackward); + QCOMPARE(cursor.selectionStart(), text.indexOf("bar")); + QCOMPARE(cursor.selectionEnd(), cursor.selectionStart() + 3); + + cursor.movePosition(QTextCursor::Start); + cursor = doc->find(regularExpression, cursor); + QCOMPARE(cursor.selectionStart(), text.indexOf("bar")); + QCOMPARE(cursor.selectionEnd(), cursor.selectionStart() + 3); + cursor = doc->find(regularExpression, cursor); + QCOMPARE(cursor.selectionStart(), text.lastIndexOf("bar")); + QCOMPARE(cursor.selectionEnd(), cursor.selectionStart() + 3); } void tst_QTextDocument::basicIsModifiedChecks() From 23e76a12b9419e1b213cbacf625d3a0b1921dd92 Mon Sep 17 00:00:00 2001 From: Samuel Gaist Date: Sun, 28 Aug 2016 17:33:35 +0200 Subject: [PATCH 62/87] Doc: add macOS example of QAbstractNativeEventFilter implementation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds a sample native event filter that can be easily integrated in a project. Task-number: QTBUG-53209 Change-Id: Iedf6df33a3de5b01dc7871cca5e7897a5b485733 Reviewed-by: Topi Reiniö --- ...orelib_kernel_qabstractnativeeventfilter.h | 49 ++++++++++++++++ ...relib_kernel_qabstractnativeeventfilter.mm | 57 +++++++++++++++++++ ...elib_kernel_qabstractnativeeventfilter.pro | 5 ++ .../kernel/qabstractnativeeventfilter.cpp | 15 ++++- 4 files changed, 124 insertions(+), 2 deletions(-) create mode 100644 src/corelib/doc/snippets/code/src_corelib_kernel_qabstractnativeeventfilter.h create mode 100644 src/corelib/doc/snippets/code/src_corelib_kernel_qabstractnativeeventfilter.mm create mode 100644 src/corelib/doc/snippets/code/src_corelib_kernel_qabstractnativeeventfilter.pro diff --git a/src/corelib/doc/snippets/code/src_corelib_kernel_qabstractnativeeventfilter.h b/src/corelib/doc/snippets/code/src_corelib_kernel_qabstractnativeeventfilter.h new file mode 100644 index 00000000000..6666bc56c5b --- /dev/null +++ b/src/corelib/doc/snippets/code/src_corelib_kernel_qabstractnativeeventfilter.h @@ -0,0 +1,49 @@ +/**************************************************************************** +** +** Copyright (C) 2016 Samuel Gaist +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +#include + +class MyCocoaEventFilter : public QAbstractNativeEventFilter +{ +public: + bool nativeEventFilter(const QByteArray &eventType, void *message, long *) Q_DECL_OVERRIDE; +}; +//! [0] diff --git a/src/corelib/doc/snippets/code/src_corelib_kernel_qabstractnativeeventfilter.mm b/src/corelib/doc/snippets/code/src_corelib_kernel_qabstractnativeeventfilter.mm new file mode 100644 index 00000000000..8abd5762596 --- /dev/null +++ b/src/corelib/doc/snippets/code/src_corelib_kernel_qabstractnativeeventfilter.mm @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2016 Samuel Gaist +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +#include "mycocoaeventfilter.h" + +#import + +bool CocoaNativeEventFilter::nativeEventFilter(const QByteArray &eventType, void *message, long *) +{ + if (eventType == "mac_generic_NSEvent") { + NSEvent *event = static_cast(message); + if ([event type] == NSKeyDown) { + // Handle key event + qDebug() << QString::fromNSString([event characters]); + } + } + return false; +} +//! [0] diff --git a/src/corelib/doc/snippets/code/src_corelib_kernel_qabstractnativeeventfilter.pro b/src/corelib/doc/snippets/code/src_corelib_kernel_qabstractnativeeventfilter.pro new file mode 100644 index 00000000000..8f447be5141 --- /dev/null +++ b/src/corelib/doc/snippets/code/src_corelib_kernel_qabstractnativeeventfilter.pro @@ -0,0 +1,5 @@ +#! [0] +HEADERS += mycocoaeventfilter.h +OBJECTIVE_SOURCES += mycocoaeventfilter.mm +LIBS += -framework AppKit +#! [0] diff --git a/src/corelib/kernel/qabstractnativeeventfilter.cpp b/src/corelib/kernel/qabstractnativeeventfilter.cpp index 9892cc7333f..15e6d17c18c 100644 --- a/src/corelib/kernel/qabstractnativeeventfilter.cpp +++ b/src/corelib/kernel/qabstractnativeeventfilter.cpp @@ -90,7 +90,7 @@ QAbstractNativeEventFilter::~QAbstractNativeEventFilter() In both cases, the \a message can be casted to a MSG pointer. The \a result pointer is only used on Windows, and corresponds to the LRESULT pointer. - On Mac, \a eventType is set to "mac_generic_NSEvent", and the \a message can be casted to an EventRef. + On macOS, \a eventType is set to "mac_generic_NSEvent", and the \a message can be casted to an NSEvent pointer. On Blackberry (not plain QNX) \a eventType is set to "bps_event_t", and the \a message can be casted to a bps_event_t pointer. @@ -99,8 +99,19 @@ QAbstractNativeEventFilter::~QAbstractNativeEventFilter() the \a message out, i.e. stop it being handled further, return true; otherwise return false. - Example: + \b {Linux example} \snippet code/src_corelib_kernel_qabstractnativeeventfilter.cpp 0 + + \b {macOS example} + + mycocoaeventfilter.h: + \snippet code/src_corelib_kernel_qabstractnativeeventfilter.h 0 + + mycocoaeventfilter.mm: + \snippet code/src_corelib_kernel_qabstractnativeeventfilter.mm 0 + + myapp.pro: + \snippet code/src_corelib_kernel_qabstractnativeeventfilter.pro 0 */ QT_END_NAMESPACE From 25e9bde2d665866f7a9a40d1ed3aa8fabcf2ac2f Mon Sep 17 00:00:00 2001 From: Takumi ASAKI Date: Thu, 14 Jul 2016 14:47:05 +0900 Subject: [PATCH 63/87] Bearer/ConnMan: Fix getTechnologies() is not called Change-Id: I4e39c971198583af815f5bcecaad4a9c52e5d2dd Reviewed-by: Lorn Potter --- src/plugins/bearer/connman/qconnmanservice_linux.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/bearer/connman/qconnmanservice_linux.cpp b/src/plugins/bearer/connman/qconnmanservice_linux.cpp index 40bab4fda6d..64c416a81d3 100644 --- a/src/plugins/bearer/connman/qconnmanservice_linux.cpp +++ b/src/plugins/bearer/connman/qconnmanservice_linux.cpp @@ -246,6 +246,8 @@ QStringList QConnmanManagerInterface::getServices() bool QConnmanManagerInterface::requestScan(const QString &type) { bool scanned = false; + if (technologiesMap.isEmpty()) + getTechnologies(); Q_FOREACH (QConnmanTechnologyInterface *tech, technologiesMap) { if (tech->type() == type) { tech->scan(); From 2ce8590e0cc0f9b1ceec98e5df1d6ccd2e804bd9 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Thu, 22 Sep 2016 09:00:15 +0200 Subject: [PATCH 64/87] win32: Fix Visual Studio project generation With the removal of Windows CE support(52623d6d) the logic of these checks have changed, as it was always true for non Windows CE builds before. This did not affect WinRT, as those mkspecs define VCPROJ_ARCH explicitly in their qmake.conf. Task-number: QTBUG-55753 Change-Id: Ie2eddf197c17fcbf7343b444cfe8940a332a545c Reviewed-by: Friedemann Kleint --- qmake/generators/win32/msvc_vcproj.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index 1155e45bd78..cb44937beaa 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -969,7 +969,7 @@ void VcprojGenerator::initProject() vcProject.Keyword = project->first("VCPROJ_KEYWORD").toQString(); if (!project->isEmpty("VCPROJ_ARCH")) { vcProject.PlatformName = project->first("VCPROJ_ARCH").toQString(); - } else if (project->isHostBuild()) { + } else { vcProject.PlatformName = (is64Bit ? "x64" : "Win32"); } vcProject.SdkVersion = project->first("WINSDK_VER").toQString(); @@ -1051,7 +1051,7 @@ void VcprojGenerator::initConfiguration() conf.ConfigurationName = conf.Name; if (!project->isEmpty("VCPROJ_ARCH")) { conf.Name += "|" + project->first("VCPROJ_ARCH"); - } else if (project->isHostBuild()) { + } else { conf.Name += (is64Bit ? "|x64" : "|Win32"); } conf.ATLMinimizesCRunTimeLibraryUsage = (project->first("ATLMinimizesCRunTimeLibraryUsage").isEmpty() ? _False : _True); From b3aa173ec4ce13a2f6a363a7b8ba9c4c23a7feb7 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Wed, 21 Sep 2016 10:31:53 +0200 Subject: [PATCH 65/87] Fix out of source builds Change-Id: I13db11320598a884ed817b4ce6f7ffefae91452e Reviewed-by: Friedemann Kleint --- src/angle/src/common/common.pri | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/angle/src/common/common.pri b/src/angle/src/common/common.pri index e9351b2c423..3da59c61e24 100644 --- a/src/angle/src/common/common.pri +++ b/src/angle/src/common/common.pri @@ -1,5 +1,5 @@ # static builds should still link ANGLE dynamically when dynamic GL is enabled -include(../../../gui/qtgui-config.pri) +include($$OUT_PWD/../../../gui/qtgui-config.pri) static:qtConfig(dynamicgl) { CONFIG -= static CONFIG += shared From 27d2593e6d7b2474bbd14e4d5a40561ae81a448b Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Tue, 20 Sep 2016 16:38:48 +0200 Subject: [PATCH 66/87] Return color bitmap from QRawFont for color fonts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the font in question is a color font, we should call the appropriate function bitmapForGlyph() and return the color bitmap from the font, rather than the alpha map in QRawFont::alphaMapForGlyph(). Change-Id: I2c3cd66db5a93ddf0cc463f4d136dd6771b9734c Reviewed-by: Tor Arne Vestbø Reviewed-by: Konstantin Ritt --- src/gui/text/qrawfont.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/gui/text/qrawfont.cpp b/src/gui/text/qrawfont.cpp index 8e6ffa5e94e..4d567b26c29 100644 --- a/src/gui/text/qrawfont.cpp +++ b/src/gui/text/qrawfont.cpp @@ -261,9 +261,13 @@ void QRawFont::loadFromData(const QByteArray &fontData, \a glyphIndex in the underlying font, using the \a transform specified. If the QRawFont is not valid, this function will return an invalid QImage. - If \a antialiasingType is set to QRawFont::SubPixelAntialiasing, then the resulting image will be - in QImage::Format_RGB32 and the RGB values of each pixel will represent the subpixel opacities of - the pixel in the rasterization of the glyph. Otherwise, the image will be in the format of + If the font is a color font, then the resulting image will contain the rendered + glyph at the current pixel size. In this case, the \a antialiasingType will be + ignored. + + Otherwise, if \a antialiasingType is set to QRawFont::SubPixelAntialiasing, then the resulting image + will be in QImage::Format_RGB32 and the RGB values of each pixel will represent the subpixel opacities + of the pixel in the rasterization of the glyph. Otherwise, the image will be in the format of QImage::Format_Indexed8 and each pixel will contain the opacity of the pixel in the rasterization. @@ -275,6 +279,9 @@ QImage QRawFont::alphaMapForGlyph(quint32 glyphIndex, AntialiasingType antialias if (!d->isValid()) return QImage(); + if (d->fontEngine->glyphFormat == QFontEngine::Format_ARGB) + return d->fontEngine->bitmapForGlyph(glyphIndex, QFixed(), transform); + if (antialiasingType == SubPixelAntialiasing) return d->fontEngine->alphaRGBMapForGlyph(glyphIndex, QFixed(), transform); From 036639c2b575de238a519cb029c4ba70d4c8980d Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Wed, 21 Sep 2016 14:55:00 +0200 Subject: [PATCH 67/87] Windows/freetype: Fix loading non-regular fonts When resolving the filenames of fonts, we would first match against the font face name, meaning that an italic font, for instance would always be matched to the file of the regular font in the same face. To fix this, we look up the full name in the file name cache first, before the face name. Also, since the font names in the registry are the English names, but the names we get when enumerating the fonts on the system can be localized on non-English locales, we need to translate the full name of the font before we give up on matching it against the registry. Since this can be a heavy operation, we add a cut-off which skips resolving the English name when the style is one of the most common "Italic" or "Bold" since we know these to be English. [ChangeLog][QtGui][Windows] Fix selecting non-regular fonts when using the Freetype engine. Task-number: QTBUG-47485 Change-Id: If897abb93dc93263902b1c62bc3f66c4d06721c2 Reviewed-by: Friedemann Kleint Reviewed-by: Lars Knoll Reviewed-by: Allan Sandfeld Jensen --- .../platforms/windows/qwindowsfontdatabase.cpp | 9 +++++++-- .../windows/qwindowsfontdatabase_ft.cpp | 16 +++++++++++++--- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp index 9f2d0c8a33e..04b95308904 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp @@ -908,7 +908,7 @@ static FontNames getCanonicalFontNames(const uchar *table, quint32 bytes) } // namespace -QString getEnglishName(const QString &familyName) +QString getEnglishName(const QString &familyName, bool includeStyle = false) { QString i18n_name; QString faceName = familyName; @@ -946,7 +946,12 @@ QString getEnglishName(const QString &familyName) if ( bytes == GDI_ERROR ) goto error; - i18n_name = getCanonicalFontNames(table, bytes).name; + { + const FontNames names = getCanonicalFontNames(table, bytes); + i18n_name = names.name; + if (includeStyle) + i18n_name += QLatin1Char(' ') + names.style; + } error: delete [] table; SelectObject( hdc, oldobj ); diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp index 4d8966f9340..f7c8dbdf23a 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp @@ -102,7 +102,7 @@ static FontFile * createFontFile(const QString &fileName, int index) } extern bool localizedName(const QString &name); -extern QString getEnglishName(const QString &familyName); +extern QString getEnglishName(const QString &familyName, bool includeStyle = false); namespace { struct FontKey @@ -235,9 +235,19 @@ static bool addFontToDatabase(const QString &faceName, } int index = 0; - const FontKey *key = findFontKey(faceName, &index); + const FontKey *key = findFontKey(fullName, &index); if (!key) { - key = findFontKey(fullName, &index); + // On non-English locales, the styles of the font may be localized in enumeration, but + // not in the registry. + QLocale systemLocale = QLocale::system(); + if (systemLocale.language() != QLocale::C + && systemLocale.language() != QLocale::English + && styleName != QLatin1String("Italic") + && styleName != QLatin1String("Bold")) { + key = findFontKey(getEnglishName(fullName, true), &index); + } + if (!key) + key = findFontKey(faceName, &index); if (!key && !registerAlias && englishName.isEmpty() && localizedName(faceName)) englishName = getEnglishName(faceName); if (!key && !englishName.isEmpty()) From b638a7da38eba2e520a0636b9b08602a556b4849 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Wed, 14 Sep 2016 14:05:05 +0200 Subject: [PATCH 68/87] eglfs: Add missing virtual layout setting for DRM/KMS Just setting virtualDesktopLayout and virtualIndex are not always enough. To create more complex shapes (e.g. a T-shaped cluster) the top-left position has to be specified explicitly. Enable this via an optional virtualPos property. This also involves improving evdevtouch's mapping functionality. Instead of fragile indices, rely on the screen name instead. Change-Id: I138840779032ad9da674bfef7763adfdfc74ccd4 Reviewed-by: Andy Nichols --- .../input/evdevtouch/qevdevtouchhandler.cpp | 30 +++++++----- .../input/shared/qtouchoutputmapping.cpp | 12 ++--- .../input/shared/qtouchoutputmapping_p.h | 4 +- .../eglfs_kms_support/qeglfskmsdevice.cpp | 48 ++++++++++++------- .../eglfs_kms_support/qeglfskmsdevice.h | 10 +++- 5 files changed, 68 insertions(+), 36 deletions(-) diff --git a/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp b/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp index 32ec9d5452a..d53a317fc59 100644 --- a/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp +++ b/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp @@ -131,7 +131,8 @@ public: bool m_typeB; QTransform m_rotate; bool m_singleTouch; - int m_screenIndex; + QString m_screenName; + QPointer m_screen; }; QEvdevTouchScreenData::QEvdevTouchScreenData(QEvdevTouchScreenHandler *q_ptr, const QStringList &args) @@ -141,8 +142,7 @@ QEvdevTouchScreenData::QEvdevTouchScreenData(QEvdevTouchScreenHandler *q_ptr, co hw_range_x_min(0), hw_range_x_max(0), hw_range_y_min(0), hw_range_y_max(0), hw_pressure_min(0), hw_pressure_max(0), - m_typeB(false), m_singleTouch(false), - m_screenIndex(-1) + m_typeB(false), m_singleTouch(false) { m_forceToActiveWindow = args.contains(QLatin1String("force_window")); } @@ -301,10 +301,10 @@ QEvdevTouchScreenHandler::QEvdevTouchScreenHandler(const QString &device, const QTouchOutputMapping mapping; if (mapping.load()) { - d->m_screenIndex = mapping.screenIndexForDeviceNode(d->deviceNode); - if (d->m_screenIndex >= 0) - qCDebug(qLcEvdevTouch, "evdevtouch: Mapping device %s to screen index %d", - qPrintable(d->deviceNode), d->m_screenIndex); + d->m_screenName = mapping.screenNameForDeviceNode(d->deviceNode); + if (!d->m_screenName.isEmpty()) + qCDebug(qLcEvdevTouch, "evdevtouch: Mapping device %s to screen %s", + qPrintable(d->deviceNode), qPrintable(d->m_screenName)); } registerTouchDevice(); @@ -673,10 +673,18 @@ void QEvdevTouchScreenData::reportPoints() // geometry in the full virtual desktop space, there is nothing else // left to do since qguiapp will handle the rest. QScreen *screen = QGuiApplication::primaryScreen(); - if (m_screenIndex >= 0) { - const QList screens = QGuiApplication::screens(); - if (m_screenIndex < screens.count()) - screen = screens.at(m_screenIndex); + if (!m_screenName.isEmpty()) { + if (!m_screen) { + const QList screens = QGuiApplication::screens(); + for (QScreen *s : screens) { + if (s->name() == m_screenName) { + m_screen = s; + break; + } + } + } + if (m_screen) + screen = m_screen; } winRect = QHighDpi::toNativePixels(screen->geometry(), screen); } diff --git a/src/platformsupport/input/shared/qtouchoutputmapping.cpp b/src/platformsupport/input/shared/qtouchoutputmapping.cpp index 55c1dc34f44..0a1afd47397 100644 --- a/src/platformsupport/input/shared/qtouchoutputmapping.cpp +++ b/src/platformsupport/input/shared/qtouchoutputmapping.cpp @@ -71,21 +71,21 @@ bool QTouchOutputMapping::load() const QVariantMap output = outputs.at(i).toObject().toVariantMap(); if (!output.contains(QStringLiteral("touchDevice"))) continue; - if (!output.contains(QStringLiteral("virtualIndex"))) { - qWarning("evdevtouch: Output %d specifies touchDevice but not virtualIndex, this is wrong", i); + if (!output.contains(QStringLiteral("name"))) { + qWarning("evdevtouch: Output %d specifies touchDevice but not name, this is wrong", i); continue; } const QString &deviceNode = output.value(QStringLiteral("touchDevice")).toString(); - const int screenIndex = output.value(QStringLiteral("virtualIndex")).toInt(); - m_screenIndexTable.insert(deviceNode, screenIndex); + const QString &screenName = output.value(QStringLiteral("name")).toString(); + m_screenTable.insert(deviceNode, screenName); } return true; } -int QTouchOutputMapping::screenIndexForDeviceNode(const QString &deviceNode) +QString QTouchOutputMapping::screenNameForDeviceNode(const QString &deviceNode) { - return m_screenIndexTable.value(deviceNode, -1); + return m_screenTable.value(deviceNode); } QT_END_NAMESPACE diff --git a/src/platformsupport/input/shared/qtouchoutputmapping_p.h b/src/platformsupport/input/shared/qtouchoutputmapping_p.h index 74999d93ce5..94d4dbc3b1a 100644 --- a/src/platformsupport/input/shared/qtouchoutputmapping_p.h +++ b/src/platformsupport/input/shared/qtouchoutputmapping_p.h @@ -60,10 +60,10 @@ class QTouchOutputMapping { public: bool load(); - int screenIndexForDeviceNode(const QString &deviceNode); + QString screenNameForDeviceNode(const QString &deviceNode); private: - QHash m_screenIndexTable; + QHash m_screenTable; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.cpp index 5944e8d51f5..a0574b1b322 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.cpp @@ -159,7 +159,9 @@ static bool parseModeline(const QByteArray &text, drmModeModeInfoPtr mode) return true; } -QEglFSKmsScreen *QEglFSKmsDevice::createScreenForConnector(drmModeResPtr resources, drmModeConnectorPtr connector, int *virtualIndex) +QEglFSKmsScreen *QEglFSKmsDevice::createScreenForConnector(drmModeResPtr resources, + drmModeConnectorPtr connector, + VirtualDesktopInfo *vinfo) { const QByteArray connectorName = nameForConnector(connector); @@ -192,8 +194,16 @@ QEglFSKmsScreen *QEglFSKmsDevice::createScreenForConnector(drmModeResPtr resourc qWarning("Invalid mode \"%s\" for output %s", mode.constData(), connectorName.constData()); configuration = OutputConfigPreferred; } - if (virtualIndex) - *virtualIndex = userConnectorConfig.value(QStringLiteral("virtualIndex"), INT_MAX).toInt(); + if (vinfo) { + *vinfo = VirtualDesktopInfo(); + vinfo->virtualIndex = userConnectorConfig.value(QStringLiteral("virtualIndex"), INT_MAX).toInt(); + if (userConnectorConfig.contains(QStringLiteral("virtualPos"))) { + const QByteArray vpos = userConnectorConfig.value(QStringLiteral("virtualPos")).toByteArray(); + const QByteArrayList vposComp = vpos.split(','); + if (vposComp.count() == 2) + vinfo->virtualPos = QPoint(vposComp[0].trimmed().toInt(), vposComp[1].trimmed().toInt()); + } + } const uint32_t crtc_id = resources->crtcs[crtc]; @@ -357,22 +367,24 @@ QEglFSKmsDevice::~QEglFSKmsDevice() struct OrderedScreen { - OrderedScreen() : screen(nullptr), index(-1) { } - OrderedScreen(QEglFSKmsScreen *screen, int index) : screen(screen), index(index) { } + OrderedScreen() : screen(nullptr) { } + OrderedScreen(QEglFSKmsScreen *screen, const QEglFSKmsDevice::VirtualDesktopInfo &vinfo) + : screen(screen), vinfo(vinfo) { } QEglFSKmsScreen *screen; - int index; + QEglFSKmsDevice::VirtualDesktopInfo vinfo; }; QDebug operator<<(QDebug dbg, const OrderedScreen &s) { QDebugStateSaver saver(dbg); - dbg.nospace() << "OrderedScreen(" << s.screen << " : " << s.index << ")"; + dbg.nospace() << "OrderedScreen(" << s.screen << " : " << s.vinfo.virtualIndex + << " / " << s.vinfo.virtualPos << ")"; return dbg; } static bool orderedScreenLessThan(const OrderedScreen &a, const OrderedScreen &b) { - return a.index < b.index; + return a.vinfo.virtualIndex < b.vinfo.virtualIndex; } void QEglFSKmsDevice::createScreens() @@ -390,10 +402,10 @@ void QEglFSKmsDevice::createScreens() if (!connector) continue; - int virtualIndex; - QEglFSKmsScreen *screen = createScreenForConnector(resources, connector, &virtualIndex); + VirtualDesktopInfo vinfo; + QEglFSKmsScreen *screen = createScreenForConnector(resources, connector, &vinfo); if (screen) - screens.append(OrderedScreen(screen, virtualIndex)); + screens.append(OrderedScreen(screen, vinfo)); drmModeFreeConnector(connector); } @@ -411,11 +423,15 @@ void QEglFSKmsDevice::createScreens() for (const OrderedScreen &orderedScreen : screens) { QEglFSKmsScreen *s = orderedScreen.screen; // set up a horizontal or vertical virtual desktop - s->setVirtualPosition(pos); - if (m_integration->virtualDesktopLayout() == QEglFSKmsIntegration::VirtualDesktopLayoutVertical) - pos.ry() += s->geometry().height(); - else - pos.rx() += s->geometry().width(); + if (orderedScreen.vinfo.virtualPos.isNull()) { + s->setVirtualPosition(pos); + if (m_integration->virtualDesktopLayout() == QEglFSKmsIntegration::VirtualDesktopLayoutVertical) + pos.ry() += s->geometry().height(); + else + pos.rx() += s->geometry().width(); + } else { + s->setVirtualPosition(orderedScreen.vinfo.virtualPos); + } qCDebug(qLcEglfsKmsDebug) << "Adding screen" << s << "to QPA with geometry" << s->geometry(); // The order in qguiapp's screens list will match the order set by // virtualIndex. This is not only handy but also required since for instance diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.h index 4aad2e0143f..3e7ac7e3f0a 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.h @@ -53,6 +53,12 @@ QT_BEGIN_NAMESPACE class Q_EGLFS_EXPORT QEglFSKmsDevice { public: + struct VirtualDesktopInfo { + VirtualDesktopInfo() : virtualIndex(0) { } + int virtualIndex; + QPoint virtualPos; + }; + QEglFSKmsDevice(QEglFSKmsIntegration *integration, const QString &path); virtual ~QEglFSKmsDevice(); @@ -79,7 +85,9 @@ protected: quint32 m_connector_allocator; int crtcForConnector(drmModeResPtr resources, drmModeConnectorPtr connector); - QEglFSKmsScreen *createScreenForConnector(drmModeResPtr resources, drmModeConnectorPtr connector, int *virtualIndex); + QEglFSKmsScreen *createScreenForConnector(drmModeResPtr resources, + drmModeConnectorPtr connector, + VirtualDesktopInfo *vinfo); drmModePropertyPtr connectorProperty(drmModeConnectorPtr connector, const QByteArray &name); static void pageFlipHandler(int fd, From 2586a62264610a55ae8d2894a6f9bee891a541f5 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 20 Sep 2016 13:15:25 +0200 Subject: [PATCH 69/87] eglfs: Move remaining sources to under api Move platform integration, context and offscreensurface to under 'api'. This allows accessing these from out-of-tree eglfs backends as well. For instance, the upcoming eglfs_emu backend for the Qt Simulator may need access to QEglFSIntegration. Clean up the project files and remove out-of-date comments (the private module QtEglFSDeviceIntegration is not really header-less since 5.7). Change-Id: If96dd5780a6bd33a1cf29164364df9bf921c4d01 Reviewed-by: Andy Nichols --- src/plugins/platforms/eglfs/api/api.pri | 8 +++++++- .../platforms/eglfs/{ => api}/qeglfscontext.cpp | 2 +- .../{qeglfscontext.h => api/qeglfscontext_p.h} | 11 +++++++++++ src/plugins/platforms/eglfs/api/qeglfscursor.cpp | 2 +- .../platforms/eglfs/api/qeglfsdeviceintegration.cpp | 2 +- .../platforms/eglfs/{ => api}/qeglfsintegration.cpp | 6 +++--- .../qeglfsintegration_p.h} | 11 +++++++++++ .../eglfs/{ => api}/qeglfsoffscreenwindow.cpp | 2 +- .../qeglfsoffscreenwindow_p.h} | 11 +++++++++++ src/plugins/platforms/eglfs/api/qeglfswindow_p.h | 2 +- .../deviceintegration/eglfs_brcm/eglfs_brcm.pro | 2 +- .../eglfs/deviceintegration/eglfs_kms/eglfs_kms.pro | 2 +- .../eglfs_kms/qeglfskmsgbmdevice.cpp | 2 +- .../eglfs_kms/qeglfskmsgbmscreen.cpp | 2 +- .../eglfs_kms_egldevice/eglfs_kms_egldevice.pro | 2 +- .../eglfs_kms_support/eglfs_kms_support.pro | 2 +- .../eglfs_kms_support/qeglfskmsdevice.cpp | 2 +- .../eglfs_kms_support/qeglfskmsscreen.cpp | 2 +- .../deviceintegration/eglfs_mali/eglfs_mali.pro | 2 +- .../eglfs/deviceintegration/eglfs_viv/eglfs_viv.pro | 2 +- .../deviceintegration/eglfs_viv_wl/eglfs_viv_wl.pro | 2 +- .../eglfs/deviceintegration/eglfs_x11/eglfs_x11.pro | 2 +- src/plugins/platforms/eglfs/eglfs-plugin.pro | 2 ++ .../platforms/eglfs/eglfsdeviceintegration.pro | 13 ++----------- src/plugins/platforms/eglfs/qeglfsmain.cpp | 2 +- 25 files changed, 65 insertions(+), 33 deletions(-) rename src/plugins/platforms/eglfs/{ => api}/qeglfscontext.cpp (99%) rename src/plugins/platforms/eglfs/{qeglfscontext.h => api/qeglfscontext_p.h} (91%) rename src/plugins/platforms/eglfs/{ => api}/qeglfsintegration.cpp (99%) rename src/plugins/platforms/eglfs/{qeglfsintegration.h => api/qeglfsintegration_p.h} (95%) rename src/plugins/platforms/eglfs/{ => api}/qeglfsoffscreenwindow.cpp (98%) rename src/plugins/platforms/eglfs/{qeglfsoffscreenwindow.h => api/qeglfsoffscreenwindow_p.h} (91%) diff --git a/src/plugins/platforms/eglfs/api/api.pri b/src/plugins/platforms/eglfs/api/api.pri index 957dee554c4..bd792dae7fb 100644 --- a/src/plugins/platforms/eglfs/api/api.pri +++ b/src/plugins/platforms/eglfs/api/api.pri @@ -3,13 +3,19 @@ SOURCES += $$PWD/qeglfswindow.cpp \ $$PWD/qeglfsscreen.cpp \ $$PWD/qeglfscursor.cpp \ $$PWD/qeglfshooks.cpp \ - $$PWD/qeglfsdeviceintegration.cpp + $$PWD/qeglfsdeviceintegration.cpp \ + $$PWD/qeglfsintegration.cpp \ + $$PWD/qeglfscontext.cpp \ + $$PWD/qeglfsoffscreenwindow.cpp HEADERS += $$PWD/qeglfswindow_p.h \ $$PWD/qeglfsscreen_p.h \ $$PWD/qeglfscursor_p.h \ $$PWD/qeglfshooks_p.h \ $$PWD/qeglfsdeviceintegration_p.h \ + $$PWD/qeglfsintegration_p.h \ + $$PWD/qeglfscontext_p.h \ + $$PWD/qeglfsoffscreenwindow_p.h \ $$PWD/qeglfsglobal.h INCLUDEPATH += $$PWD diff --git a/src/plugins/platforms/eglfs/qeglfscontext.cpp b/src/plugins/platforms/eglfs/api/qeglfscontext.cpp similarity index 99% rename from src/plugins/platforms/eglfs/qeglfscontext.cpp rename to src/plugins/platforms/eglfs/api/qeglfscontext.cpp index 8d479873cfa..8e44b3e93e9 100644 --- a/src/plugins/platforms/eglfs/qeglfscontext.cpp +++ b/src/plugins/platforms/eglfs/api/qeglfscontext.cpp @@ -42,7 +42,7 @@ #include #include -#include "qeglfscontext.h" +#include "qeglfscontext_p.h" #include "qeglfswindow_p.h" #include "qeglfshooks_p.h" #include "qeglfscursor_p.h" diff --git a/src/plugins/platforms/eglfs/qeglfscontext.h b/src/plugins/platforms/eglfs/api/qeglfscontext_p.h similarity index 91% rename from src/plugins/platforms/eglfs/qeglfscontext.h rename to src/plugins/platforms/eglfs/api/qeglfscontext_p.h index 91c5a7910b9..2274e488ff8 100644 --- a/src/plugins/platforms/eglfs/qeglfscontext.h +++ b/src/plugins/platforms/eglfs/api/qeglfscontext_p.h @@ -40,6 +40,17 @@ #ifndef QEGLFSCONTEXT_H #define QEGLFSCONTEXT_H +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + #include "qeglfsglobal.h" #include #include diff --git a/src/plugins/platforms/eglfs/api/qeglfscursor.cpp b/src/plugins/platforms/eglfs/api/qeglfscursor.cpp index 0040ecd59d9..1b3446c4ac8 100644 --- a/src/plugins/platforms/eglfs/api/qeglfscursor.cpp +++ b/src/plugins/platforms/eglfs/api/qeglfscursor.cpp @@ -38,7 +38,7 @@ ****************************************************************************/ #include "qeglfscursor_p.h" -#include "qeglfsintegration.h" +#include "qeglfsintegration_p.h" #include "qeglfsscreen_p.h" #include diff --git a/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration.cpp b/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration.cpp index 6f659299138..9f057673661 100644 --- a/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration.cpp +++ b/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration.cpp @@ -38,7 +38,7 @@ ****************************************************************************/ #include "qeglfsdeviceintegration_p.h" -#include "qeglfsintegration.h" +#include "qeglfsintegration_p.h" #include "qeglfscursor_p.h" #include "qeglfswindow_p.h" #include "qeglfsscreen_p.h" diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/api/qeglfsintegration.cpp similarity index 99% rename from src/plugins/platforms/eglfs/qeglfsintegration.cpp rename to src/plugins/platforms/eglfs/api/qeglfsintegration.cpp index 418ff6119bc..4974499e0a2 100644 --- a/src/plugins/platforms/eglfs/qeglfsintegration.cpp +++ b/src/plugins/platforms/eglfs/api/qeglfsintegration.cpp @@ -51,11 +51,11 @@ #include #include -#include "qeglfsintegration.h" +#include "qeglfsintegration_p.h" #include "qeglfswindow_p.h" #include "qeglfshooks_p.h" -#include "qeglfscontext.h" -#include "qeglfsoffscreenwindow.h" +#include "qeglfscontext_p.h" +#include "qeglfsoffscreenwindow_p.h" #include "qeglfscursor_p.h" #include diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.h b/src/plugins/platforms/eglfs/api/qeglfsintegration_p.h similarity index 95% rename from src/plugins/platforms/eglfs/qeglfsintegration.h rename to src/plugins/platforms/eglfs/api/qeglfsintegration_p.h index 9c5439a22f0..861a11e5787 100644 --- a/src/plugins/platforms/eglfs/qeglfsintegration.h +++ b/src/plugins/platforms/eglfs/api/qeglfsintegration_p.h @@ -40,6 +40,17 @@ #ifndef QEGLFSINTEGRATION_H #define QEGLFSINTEGRATION_H +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + #include "qeglfsglobal.h" #include #include diff --git a/src/plugins/platforms/eglfs/qeglfsoffscreenwindow.cpp b/src/plugins/platforms/eglfs/api/qeglfsoffscreenwindow.cpp similarity index 98% rename from src/plugins/platforms/eglfs/qeglfsoffscreenwindow.cpp rename to src/plugins/platforms/eglfs/api/qeglfsoffscreenwindow.cpp index 0334ac97856..7de5379ae3d 100644 --- a/src/plugins/platforms/eglfs/qeglfsoffscreenwindow.cpp +++ b/src/plugins/platforms/eglfs/api/qeglfsoffscreenwindow.cpp @@ -37,7 +37,7 @@ ** ****************************************************************************/ -#include "qeglfsoffscreenwindow.h" +#include "qeglfsoffscreenwindow_p.h" #include "qeglfshooks_p.h" #include #include diff --git a/src/plugins/platforms/eglfs/qeglfsoffscreenwindow.h b/src/plugins/platforms/eglfs/api/qeglfsoffscreenwindow_p.h similarity index 91% rename from src/plugins/platforms/eglfs/qeglfsoffscreenwindow.h rename to src/plugins/platforms/eglfs/api/qeglfsoffscreenwindow_p.h index 673fa0d7297..da9d9b0fd65 100644 --- a/src/plugins/platforms/eglfs/qeglfsoffscreenwindow.h +++ b/src/plugins/platforms/eglfs/api/qeglfsoffscreenwindow_p.h @@ -40,6 +40,17 @@ #ifndef QEGLFSOFFSCREENWINDOW_H #define QEGLFSOFFSCREENWINDOW_H +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + #include "qeglfsglobal.h" #include diff --git a/src/plugins/platforms/eglfs/api/qeglfswindow_p.h b/src/plugins/platforms/eglfs/api/qeglfswindow_p.h index aea4ed48065..dd1d2d6fc7b 100644 --- a/src/plugins/platforms/eglfs/api/qeglfswindow_p.h +++ b/src/plugins/platforms/eglfs/api/qeglfswindow_p.h @@ -52,7 +52,7 @@ // #include "qeglfsglobal.h" -#include "qeglfsintegration.h" +#include "qeglfsintegration_p.h" #include "qeglfsscreen_p.h" #include diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/eglfs_brcm.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/eglfs_brcm.pro index d65e136a960..7f1e7b9f59a 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/eglfs_brcm.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/eglfs_brcm.pro @@ -2,7 +2,7 @@ TARGET = qeglfs-brcm-integration QT += core-private gui-private platformsupport-private eglfsdeviceintegration-private -INCLUDEPATH += $$PWD/../.. +INCLUDEPATH += $$PWD/../../api CONFIG += egl LIBS += -lbcm_host diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/eglfs_kms.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/eglfs_kms.pro index 70ff054172d..10571dc978d 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/eglfs_kms.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/eglfs_kms.pro @@ -6,7 +6,7 @@ load(qt_plugin) QT += core-private gui-private platformsupport-private eglfsdeviceintegration-private eglfs_kms_support-private -INCLUDEPATH += $$PWD/../.. $$PWD/../eglfs_kms_support +INCLUDEPATH += $$PWD/../../api $$PWD/../eglfs_kms_support # Avoid X11 header collision, use generic EGL native types DEFINES += QT_EGL_NO_X11 diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp index 99f6cfb0ca3..3a220ec9429 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp @@ -42,7 +42,7 @@ #include "qeglfskmsgbmdevice.h" #include "qeglfskmsgbmscreen.h" -#include "qeglfsintegration.h" +#include "qeglfsintegration_p.h" #include #include diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp index dde386fc578..75ff3ac749f 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp @@ -42,7 +42,7 @@ #include "qeglfskmsgbmscreen.h" #include "qeglfskmsgbmdevice.h" #include "qeglfskmsgbmcursor.h" -#include "qeglfsintegration.h" +#include "qeglfsintegration_p.h" #include diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.pro index 5f47b98369d..582982df76d 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.pro @@ -2,7 +2,7 @@ TARGET = qeglfs-kms-egldevice-integration QT += core-private gui-private platformsupport-private eglfsdeviceintegration-private eglfs_kms_support-private -INCLUDEPATH += $$PWD/../.. $$PWD/../eglfs_kms_support +INCLUDEPATH += $$PWD/../../api $$PWD/../eglfs_kms_support # Avoid X11 header collision, use generic EGL native types DEFINES += QT_EGL_NO_X11 diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/eglfs_kms_support.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/eglfs_kms_support.pro index 464c64539fe..f88a7c847e1 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/eglfs_kms_support.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/eglfs_kms_support.pro @@ -4,7 +4,7 @@ load(qt_module) QT += core-private gui-private platformsupport-private eglfsdeviceintegration-private -INCLUDEPATH += $$PWD/../.. +INCLUDEPATH += $$PWD/../../api # Avoid X11 header collision, use generic EGL native types DEFINES += QT_EGL_NO_X11 diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.cpp index a0574b1b322..bf96a7d6836 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.cpp @@ -42,7 +42,7 @@ #include "qeglfskmsdevice.h" #include "qeglfskmsscreen.h" -#include "qeglfsintegration.h" +#include "qeglfsintegration_p.h" #include #include diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp index f690cd668ed..e4b6c67f287 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp @@ -41,7 +41,7 @@ #include "qeglfskmsscreen.h" #include "qeglfskmsdevice.h" -#include "qeglfsintegration.h" +#include "qeglfsintegration_p.h" #include diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/eglfs_mali.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/eglfs_mali.pro index 6e32ca26d05..e72f5bdd148 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/eglfs_mali.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/eglfs_mali.pro @@ -5,7 +5,7 @@ QT += core-private gui-private platformsupport-private eglfsdeviceintegration-pr # Avoid X11 header collision, use generic EGL native types DEFINES += QT_EGL_NO_X11 -INCLUDEPATH += $$PWD/../.. +INCLUDEPATH += $$PWD/../../api CONFIG += egl QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/eglfs_viv.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/eglfs_viv.pro index 16880535e30..364812ec605 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/eglfs_viv.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/eglfs_viv.pro @@ -2,7 +2,7 @@ TARGET = qeglfs-viv-integration QT += core-private gui-private platformsupport-private eglfsdeviceintegration-private -INCLUDEPATH += $$PWD/../.. +INCLUDEPATH += $$PWD/../../api CONFIG += egl DEFINES += LINUX=1 EGL_API_FB=1 QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/eglfs_viv_wl.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/eglfs_viv_wl.pro index 374c5bba6b6..ccdf20b4173 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/eglfs_viv_wl.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/eglfs_viv_wl.pro @@ -2,7 +2,7 @@ TARGET = qeglfs-viv-wl-integration QT += core-private gui-private platformsupport-private eglfsdeviceintegration-private -INCLUDEPATH += $$PWD/../.. +INCLUDEPATH += $$PWD/../../api CONFIG += egl DEFINES += LINUX=1 EGL_API_FB=1 QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/eglfs_x11.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/eglfs_x11.pro index 10af57e4876..51a026e2cfd 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/eglfs_x11.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/eglfs_x11.pro @@ -5,7 +5,7 @@ QT += core-private gui-private platformsupport-private eglfsdeviceintegration-pr # Avoid X11 header collision, use generic EGL native types DEFINES += QT_EGL_NO_X11 -INCLUDEPATH += $$PWD/../.. +INCLUDEPATH += $$PWD/../../api CONFIG += egl QMAKE_USE += xcb_xlib diff --git a/src/plugins/platforms/eglfs/eglfs-plugin.pro b/src/plugins/platforms/eglfs/eglfs-plugin.pro index 90b8a9fb323..d8adc132265 100644 --- a/src/plugins/platforms/eglfs/eglfs-plugin.pro +++ b/src/plugins/platforms/eglfs/eglfs-plugin.pro @@ -6,6 +6,8 @@ SOURCES += $$PWD/qeglfsmain.cpp OTHER_FILES += $$PWD/eglfs.json +INCLUDEPATH += $$PWD/api + PLUGIN_TYPE = platforms PLUGIN_CLASS_NAME = QEglFSIntegrationPlugin !equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - diff --git a/src/plugins/platforms/eglfs/eglfsdeviceintegration.pro b/src/plugins/platforms/eglfs/eglfsdeviceintegration.pro index eb0ce731180..15a825a7b0b 100644 --- a/src/plugins/platforms/eglfs/eglfsdeviceintegration.pro +++ b/src/plugins/platforms/eglfs/eglfsdeviceintegration.pro @@ -1,7 +1,8 @@ # The device integration plugin base class has to live in a shared library, # placing it into a static lib like platformsupport is not sufficient since we # have to keep the QObject magic like qobject_cast working. -# Hence this header-less, private-only module. +# Hence this private-only module. +# By having _p headers, it also enables developing out-of-tree integration plugins. TARGET = QtEglFSDeviceIntegration CONFIG += internal_module @@ -15,20 +16,10 @@ DEFINES += QT_EGL_NO_X11 DEFINES += QT_BUILD_EGL_DEVICE_LIB -SOURCES += $$PWD/qeglfsintegration.cpp \ - $$PWD/qeglfscontext.cpp \ - $$PWD/qeglfsoffscreenwindow.cpp \ - -HEADERS += $$PWD/qeglfsintegration.h \ - $$PWD/qeglfscontext.h \ - $$PWD/qeglfsoffscreenwindow.h \ - include($$PWD/api/api.pri) QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF -INCLUDEPATH += $$PWD - !isEmpty(EGLFS_PLATFORM_HOOKS_SOURCES) { HEADERS += $$EGLFS_PLATFORM_HOOKS_HEADERS SOURCES += $$EGLFS_PLATFORM_HOOKS_SOURCES diff --git a/src/plugins/platforms/eglfs/qeglfsmain.cpp b/src/plugins/platforms/eglfs/qeglfsmain.cpp index 50279ad110a..2885d397c6a 100644 --- a/src/plugins/platforms/eglfs/qeglfsmain.cpp +++ b/src/plugins/platforms/eglfs/qeglfsmain.cpp @@ -38,7 +38,7 @@ ****************************************************************************/ #include -#include "qeglfsintegration.h" +#include "qeglfsintegration_p.h" QT_BEGIN_NAMESPACE From 7c713701bb302a27cb48b3fda8976e3b2602913f Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 20 Sep 2016 13:39:56 +0200 Subject: [PATCH 70/87] eglfs: make qeglfsglobal.h private To avoid build system warnings about including _p headers. There is no real reason to have this as a .h header anymore, now that it is in the device integration private module. Change-Id: I16526419356284e66861f95d1d0553abf0711218 Reviewed-by: Ulf Hermann Reviewed-by: Giulio Camuffo Reviewed-by: Andy Nichols --- src/plugins/platforms/eglfs/api/api.pri | 2 +- src/plugins/platforms/eglfs/api/qeglfscontext.cpp | 2 +- src/plugins/platforms/eglfs/api/qeglfscontext_p.h | 2 +- src/plugins/platforms/eglfs/api/qeglfscursor_p.h | 2 +- .../platforms/eglfs/api/qeglfsdeviceintegration_p.h | 2 +- .../eglfs/api/{qeglfsglobal.h => qeglfsglobal_p.h} | 11 +++++++++++ src/plugins/platforms/eglfs/api/qeglfshooks_p.h | 2 +- src/plugins/platforms/eglfs/api/qeglfsintegration_p.h | 2 +- .../platforms/eglfs/api/qeglfsoffscreenwindow_p.h | 2 +- src/plugins/platforms/eglfs/api/qeglfsscreen_p.h | 2 +- src/plugins/platforms/eglfs/api/qeglfswindow_p.h | 2 +- 11 files changed, 21 insertions(+), 10 deletions(-) rename src/plugins/platforms/eglfs/api/{qeglfsglobal.h => qeglfsglobal_p.h} (90%) diff --git a/src/plugins/platforms/eglfs/api/api.pri b/src/plugins/platforms/eglfs/api/api.pri index bd792dae7fb..0ea65bd1ff3 100644 --- a/src/plugins/platforms/eglfs/api/api.pri +++ b/src/plugins/platforms/eglfs/api/api.pri @@ -16,6 +16,6 @@ HEADERS += $$PWD/qeglfswindow_p.h \ $$PWD/qeglfsintegration_p.h \ $$PWD/qeglfscontext_p.h \ $$PWD/qeglfsoffscreenwindow_p.h \ - $$PWD/qeglfsglobal.h + $$PWD/qeglfsglobal_p.h INCLUDEPATH += $$PWD diff --git a/src/plugins/platforms/eglfs/api/qeglfscontext.cpp b/src/plugins/platforms/eglfs/api/qeglfscontext.cpp index 8e44b3e93e9..1a332152950 100644 --- a/src/plugins/platforms/eglfs/api/qeglfscontext.cpp +++ b/src/plugins/platforms/eglfs/api/qeglfscontext.cpp @@ -37,7 +37,7 @@ ** ****************************************************************************/ -#include "qeglfsglobal.h" +#include "qeglfsglobal_p.h" #include #include #include diff --git a/src/plugins/platforms/eglfs/api/qeglfscontext_p.h b/src/plugins/platforms/eglfs/api/qeglfscontext_p.h index 2274e488ff8..65af3a7ceec 100644 --- a/src/plugins/platforms/eglfs/api/qeglfscontext_p.h +++ b/src/plugins/platforms/eglfs/api/qeglfscontext_p.h @@ -51,7 +51,7 @@ // We mean it. // -#include "qeglfsglobal.h" +#include "qeglfsglobal_p.h" #include #include diff --git a/src/plugins/platforms/eglfs/api/qeglfscursor_p.h b/src/plugins/platforms/eglfs/api/qeglfscursor_p.h index 8ccbe4493c9..bf6dbc8a212 100644 --- a/src/plugins/platforms/eglfs/api/qeglfscursor_p.h +++ b/src/plugins/platforms/eglfs/api/qeglfscursor_p.h @@ -51,7 +51,7 @@ // We mean it. // -#include "qeglfsglobal.h" +#include "qeglfsglobal_p.h" #include #include #include diff --git a/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration_p.h b/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration_p.h index 819e4818ab1..4335554912b 100644 --- a/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration_p.h +++ b/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration_p.h @@ -51,7 +51,7 @@ // We mean it. // -#include "qeglfsglobal.h" +#include "qeglfsglobal_p.h" #include #include #include diff --git a/src/plugins/platforms/eglfs/api/qeglfsglobal.h b/src/plugins/platforms/eglfs/api/qeglfsglobal_p.h similarity index 90% rename from src/plugins/platforms/eglfs/api/qeglfsglobal.h rename to src/plugins/platforms/eglfs/api/qeglfsglobal_p.h index 655ab7eaef0..bad5095d21b 100644 --- a/src/plugins/platforms/eglfs/api/qeglfsglobal.h +++ b/src/plugins/platforms/eglfs/api/qeglfsglobal_p.h @@ -40,6 +40,17 @@ #ifndef QEGLFSGLOBAL_H #define QEGLFSGLOBAL_H +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + #include #include diff --git a/src/plugins/platforms/eglfs/api/qeglfshooks_p.h b/src/plugins/platforms/eglfs/api/qeglfshooks_p.h index e379f7a76d2..4c3149c7c96 100644 --- a/src/plugins/platforms/eglfs/api/qeglfshooks_p.h +++ b/src/plugins/platforms/eglfs/api/qeglfshooks_p.h @@ -51,7 +51,7 @@ // We mean it. // -#include "qeglfsglobal.h" +#include "qeglfsglobal_p.h" #include "qeglfsdeviceintegration_p.h" QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/eglfs/api/qeglfsintegration_p.h b/src/plugins/platforms/eglfs/api/qeglfsintegration_p.h index 861a11e5787..1a3a44d4410 100644 --- a/src/plugins/platforms/eglfs/api/qeglfsintegration_p.h +++ b/src/plugins/platforms/eglfs/api/qeglfsintegration_p.h @@ -51,7 +51,7 @@ // We mean it. // -#include "qeglfsglobal.h" +#include "qeglfsglobal_p.h" #include #include #include diff --git a/src/plugins/platforms/eglfs/api/qeglfsoffscreenwindow_p.h b/src/plugins/platforms/eglfs/api/qeglfsoffscreenwindow_p.h index da9d9b0fd65..ec483c64e22 100644 --- a/src/plugins/platforms/eglfs/api/qeglfsoffscreenwindow_p.h +++ b/src/plugins/platforms/eglfs/api/qeglfsoffscreenwindow_p.h @@ -51,7 +51,7 @@ // We mean it. // -#include "qeglfsglobal.h" +#include "qeglfsglobal_p.h" #include QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/eglfs/api/qeglfsscreen_p.h b/src/plugins/platforms/eglfs/api/qeglfsscreen_p.h index daba9fc5917..131e619e062 100644 --- a/src/plugins/platforms/eglfs/api/qeglfsscreen_p.h +++ b/src/plugins/platforms/eglfs/api/qeglfsscreen_p.h @@ -51,7 +51,7 @@ // We mean it. // -#include "qeglfsglobal.h" +#include "qeglfsglobal_p.h" #include #include diff --git a/src/plugins/platforms/eglfs/api/qeglfswindow_p.h b/src/plugins/platforms/eglfs/api/qeglfswindow_p.h index dd1d2d6fc7b..6e752b8f79d 100644 --- a/src/plugins/platforms/eglfs/api/qeglfswindow_p.h +++ b/src/plugins/platforms/eglfs/api/qeglfswindow_p.h @@ -51,7 +51,7 @@ // We mean it. // -#include "qeglfsglobal.h" +#include "qeglfsglobal_p.h" #include "qeglfsintegration_p.h" #include "qeglfsscreen_p.h" From e0254fdacc41b89fc515e12766fcf2db1e4929ed Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Wed, 7 Sep 2016 17:26:01 -0700 Subject: [PATCH 71/87] Fixed double delete in bsdfb plugin on app exit Fixed double delete of QBsdFbScreen in destructor, first it was deleted in destroyScreen, then as a smart pointer. Take ownership of pointer before passing it to destroyScreen to avoid second delete. Change-Id: I252fcd1f31a32b463ecefce5b7139c4b3c857d33 Reviewed-by: Laszlo Agocs --- src/plugins/platforms/bsdfb/qbsdfbintegration.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/bsdfb/qbsdfbintegration.cpp b/src/plugins/platforms/bsdfb/qbsdfbintegration.cpp index e935d89c9fc..9c25076c9ca 100644 --- a/src/plugins/platforms/bsdfb/qbsdfbintegration.cpp +++ b/src/plugins/platforms/bsdfb/qbsdfbintegration.cpp @@ -63,7 +63,7 @@ QBsdFbIntegration::QBsdFbIntegration(const QStringList ¶mList) QBsdFbIntegration::~QBsdFbIntegration() { - destroyScreen(m_primaryScreen.data()); + destroyScreen(m_primaryScreen.take()); } void QBsdFbIntegration::initialize() From 524b59b0f51b554ecabbf2663891f9ae1650d122 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 21 Sep 2016 15:15:22 +0200 Subject: [PATCH 72/87] Rename QPA ExposeEvent's window-pointer from 'exposed' to 'window' The former is easy to mistake for the isExposed state of the event. Change-Id: Ic769ac332901ac97449ebc8dcca5959b6b42df68 Reviewed-by: Paul Olav Tvete --- src/gui/kernel/qguiapplication.cpp | 4 ++-- src/gui/kernel/qwindowsysteminterface.cpp | 6 +++--- src/gui/kernel/qwindowsysteminterface_p.h | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 2ed7eb2cfbf..16add8f6273 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -2794,10 +2794,10 @@ void QGuiApplicationPrivate::reportRefreshRateChange(QWindowSystemInterfacePriva void QGuiApplicationPrivate::processExposeEvent(QWindowSystemInterfacePrivate::ExposeEvent *e) { - if (!e->exposed) + if (!e->window) return; - QWindow *window = e->exposed.data(); + QWindow *window = e->window.data(); if (!window) return; QWindowPrivate *p = qt_window_private(window); diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp index 7c6bbc26c86..bb778bc5fc7 100644 --- a/src/gui/kernel/qwindowsysteminterface.cpp +++ b/src/gui/kernel/qwindowsysteminterface.cpp @@ -361,10 +361,10 @@ void QWindowSystemInterface::handleWheelEvent(QWindow *tlw, ulong timestamp, con } -QWindowSystemInterfacePrivate::ExposeEvent::ExposeEvent(QWindow *exposed, const QRegion ®ion) +QWindowSystemInterfacePrivate::ExposeEvent::ExposeEvent(QWindow *window, const QRegion ®ion) : WindowSystemEvent(Expose) - , exposed(exposed) - , isExposed(exposed && exposed->handle() ? exposed->handle()->isExposed() : false) + , window(window) + , isExposed(window && window->handle() ? window->handle()->isExposed() : false) , region(region) { } diff --git a/src/gui/kernel/qwindowsysteminterface_p.h b/src/gui/kernel/qwindowsysteminterface_p.h index bdbf191cbdf..f471e1f550c 100644 --- a/src/gui/kernel/qwindowsysteminterface_p.h +++ b/src/gui/kernel/qwindowsysteminterface_p.h @@ -330,8 +330,8 @@ public: class ExposeEvent : public WindowSystemEvent { public: - ExposeEvent(QWindow *exposed, const QRegion ®ion); - QPointer exposed; + ExposeEvent(QWindow *window, const QRegion ®ion); + QPointer window; bool isExposed; QRegion region; }; From 0deb0796a42a64930f2d977cd4041c5f1c047187 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 14 Sep 2016 15:01:13 +0200 Subject: [PATCH 73/87] Modernize rasterwindow/openglwindow examples to use requestUpdate() Change-Id: Ib8d0c42db7343247d0431ea008eb17da9ee98f4d Reviewed-by: Laszlo Agocs --- examples/gui/doc/src/openglwindow.qdoc | 12 +++++++----- examples/gui/doc/src/rasterwindow.qdoc | 15 ++++++--------- examples/gui/openglwindow/openglwindow.cpp | 7 +------ examples/gui/openglwindow/openglwindow.h | 1 - examples/gui/rasterwindow/rasterwindow.cpp | 10 ++-------- examples/gui/rasterwindow/rasterwindow.h | 1 - src/gui/kernel/qwindow.cpp | 11 +++++++---- 7 files changed, 23 insertions(+), 34 deletions(-) diff --git a/examples/gui/doc/src/openglwindow.qdoc b/examples/gui/doc/src/openglwindow.qdoc index e93451c9a5b..f283c7cfc0e 100644 --- a/examples/gui/doc/src/openglwindow.qdoc +++ b/examples/gui/doc/src/openglwindow.qdoc @@ -34,6 +34,9 @@ \image openglwindow-example.png Screenshot of the OpenGLWindow example + \note This is a low level example of how to use QWindow with OpenGL. + In practice you should consider using the higher level QOpenGLWindow class. + \section1 OpenGLWindow Super Class Our OpenGLWindow class acts as an API which is then subclassed to do the @@ -70,9 +73,8 @@ \snippet openglwindow/openglwindow.cpp 2 - The renderLater() function simply puts an update request event on - the event loop, which leads to renderNow() being called once the event - gets processed. + The renderLater() function simply calls QWindow::requestUpdate() to schedule + an update for when the system is ready to repaint. We also call renderNow() when we get an expose event. The exposeEvent() is the notification to the window that its exposure, meaning visibility, on @@ -109,11 +111,11 @@ \l {http://www.khronos.org/registry/gles/}{Khronos OpenGL ES API Registry}. If animation has been enabled with OpenGLWindow::setAnimating(true), we - call renderLater() to put another update request on the event loop. + call renderLater() to schedule another update request. \snippet openglwindow/openglwindow.cpp 4 - Enabling animation also triggers an update request as shown in the + Enabling animation also schedules an update request as shown in the following code snippet. \snippet openglwindow/openglwindow.cpp 5 diff --git a/examples/gui/doc/src/rasterwindow.qdoc b/examples/gui/doc/src/rasterwindow.qdoc index 963d09971d6..d2769250596 100644 --- a/examples/gui/doc/src/rasterwindow.qdoc +++ b/examples/gui/doc/src/rasterwindow.qdoc @@ -143,19 +143,16 @@ \snippet rasterwindow/rasterwindow.cpp 6 We went through a few places where the window needed to repainted - immediately. There are some cases where this is not desierable, + immediately. There are some cases where this is not desirable, but rather let the application return to the event loop and - later. We acheive this by posting an even to ourself which will - then be delivered when the application returns to the \l - QGuiApplication event loop. To avoid posting new requests when one - is already pending, we store this state in the \c m_update_pending - variable. + schedule the repaint for later. We achieve this by requesting + an update, using QWindow::requestUpdate(), which will then be + delivered when the system is ready to repaint. \snippet rasterwindow/rasterwindow.cpp 7 We reimplement the virtual \l QObject::event() function to handle - the update event we posted to ourselves. When the event comes in - we reset the pending update flag and call renderNow() to render - the window right away. + the update event. When the event comes in we call renderNow() to + render the window right away. */ diff --git a/examples/gui/openglwindow/openglwindow.cpp b/examples/gui/openglwindow/openglwindow.cpp index d36614f6a0b..57a996a8766 100644 --- a/examples/gui/openglwindow/openglwindow.cpp +++ b/examples/gui/openglwindow/openglwindow.cpp @@ -59,7 +59,6 @@ //! [1] OpenGLWindow::OpenGLWindow(QWindow *parent) : QWindow(parent) - , m_update_pending(false) , m_animating(false) , m_context(0) , m_device(0) @@ -99,17 +98,13 @@ void OpenGLWindow::render() //! [3] void OpenGLWindow::renderLater() { - if (!m_update_pending) { - m_update_pending = true; - QCoreApplication::postEvent(this, new QEvent(QEvent::UpdateRequest)); - } + requestUpdate(); } bool OpenGLWindow::event(QEvent *event) { switch (event->type()) { case QEvent::UpdateRequest: - m_update_pending = false; renderNow(); return true; default: diff --git a/examples/gui/openglwindow/openglwindow.h b/examples/gui/openglwindow/openglwindow.h index 276f94f84c3..6e6c1d74496 100644 --- a/examples/gui/openglwindow/openglwindow.h +++ b/examples/gui/openglwindow/openglwindow.h @@ -82,7 +82,6 @@ protected: void exposeEvent(QExposeEvent *event) override; private: - bool m_update_pending; bool m_animating; QOpenGLContext *m_context; diff --git a/examples/gui/rasterwindow/rasterwindow.cpp b/examples/gui/rasterwindow/rasterwindow.cpp index eb34bec2525..fb717a4c8a0 100644 --- a/examples/gui/rasterwindow/rasterwindow.cpp +++ b/examples/gui/rasterwindow/rasterwindow.cpp @@ -53,7 +53,6 @@ //! [1] RasterWindow::RasterWindow(QWindow *parent) : QWindow(parent) - , m_update_pending(false) { create(); m_backingStore = new QBackingStore(this); @@ -68,7 +67,6 @@ RasterWindow::RasterWindow(QWindow *parent) bool RasterWindow::event(QEvent *event) { if (event->type() == QEvent::UpdateRequest) { - m_update_pending = false; renderNow(); return true; } @@ -79,10 +77,7 @@ bool RasterWindow::event(QEvent *event) //! [6] void RasterWindow::renderLater() { - if (!m_update_pending) { - m_update_pending = true; - QCoreApplication::postEvent(this, new QEvent(QEvent::UpdateRequest)); - } + requestUpdate(); } //! [6] @@ -99,9 +94,8 @@ void RasterWindow::resizeEvent(QResizeEvent *resizeEvent) //! [2] void RasterWindow::exposeEvent(QExposeEvent *) { - if (isExposed()) { + if (isExposed()) renderNow(); - } } //! [2] diff --git a/examples/gui/rasterwindow/rasterwindow.h b/examples/gui/rasterwindow/rasterwindow.h index be640814d41..2ccecbf7043 100644 --- a/examples/gui/rasterwindow/rasterwindow.h +++ b/examples/gui/rasterwindow/rasterwindow.h @@ -74,7 +74,6 @@ protected: private: QBackingStore *m_backingStore; - bool m_update_pending; }; //! [1] #endif // RASTERWINDOW_H diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 18e8bcf99cb..23e783fcb4c 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -2175,11 +2175,14 @@ void QWindowPrivate::deliverUpdateRequest() Schedules a QEvent::UpdateRequest event to be delivered to this window. The event is delivered in sync with the display vsync on platforms - where this is possible. When driving animations, this function should - be called once after drawing has completed. + where this is possible. Otherwise, the event is delivered after a + delay of 5 ms. The additional time is there to give the event loop + a bit of idle time to gather system events, and can be overridden + using the QT_QPA_UPDATE_IDLE_TIME environment variable. - Calling this function multiple times will result in a single event - being delivered to the window. + When driving animations, this function should be called once after drawing + has completed. Calling this function multiple times will result in a single + event being delivered to the window. Subclasses of QWindow should reimplement event(), intercept the event and call the application's rendering code, then call the base class From 3bd5876c89c13a22666fdd0b05fb38969eaa5f70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Tue, 16 Aug 2016 14:52:14 +0200 Subject: [PATCH 74/87] Cocoa: Add drawBackingStoreUsingCoreGraphics MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drawRect is a general “repaint now” function, which we should handle also for OpenGL content. Make that clearer by moving the implementation details of drawing the raster backing store using CoreGraphics to a separate function. Behavior change: Call invalidateWindowShadowIfNeeded also for the OpenGL case. Change-Id: I158ebef548e063f826db2dc708c14ab1d784b095 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/cocoa/qnsview.h | 1 + src/plugins/platforms/cocoa/qnsview.mm | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h index 02ae64a58e7..963b29ebbb4 100644 --- a/src/plugins/platforms/cocoa/qnsview.h +++ b/src/plugins/platforms/cocoa/qnsview.h @@ -101,6 +101,7 @@ Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper)); - (void)setMaskRegion:(const QRegion *)region; - (void)invalidateWindowShadowIfNeeded; - (void)drawRect:(NSRect)dirtyRect; +- (void)drawBackingStoreUsingCoreGraphics:(NSRect)dirtyRect; - (void)updateGeometry; - (void)notifyWindowStateChanged:(Qt::WindowState)newState; - (void)windowNotification : (NSNotification *) windowNotification; diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 22a32c7cebd..72ac3431de5 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -569,6 +569,18 @@ static bool _q_dontOverrideCtrlLMB = false; if (m_platformWindow->m_drawContentBorderGradient) NSDrawWindowBackground(dirtyRect); + if (m_backingStore) + [self drawBackingStoreUsingCoreGraphics:dirtyRect]; + + [self invalidateWindowShadowIfNeeded]; +} + +// Draws the backing store content to the QNSView using Core Graphics. +// This function assumes that the QNSView is in a configuration that +// supports Core Graphics, such as "classic" mode or layer mode with +// the default layer. +- (void)drawBackingStoreUsingCoreGraphics:(NSRect)dirtyRect +{ if (!m_backingStore) return; @@ -623,8 +635,6 @@ static bool _q_dontOverrideCtrlLMB = false; CGImageRelease(cleanImg); CGImageRelease(subMask); CGImageRelease(bsCGImage); - - [self invalidateWindowShadowIfNeeded]; } - (BOOL) isFlipped From 690587e922f83b04163c4ade574371905d683d9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Wed, 17 Aug 2016 13:12:28 +0200 Subject: [PATCH 75/87] =?UTF-8?q?QPaintDeviceWindow:=20Don=E2=80=99t=20req?= =?UTF-8?q?uest=20update=20on=20hide?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is not the time to update and the window is repainted on expose anyway. Change-Id: I07680a2c351d337e2f35a18b804a03631d5cedc5 Reviewed-by: Jake Petroules Reviewed-by: Tor Arne Vestbø --- src/gui/kernel/qpaintdevicewindow.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/gui/kernel/qpaintdevicewindow.cpp b/src/gui/kernel/qpaintdevicewindow.cpp index c35478da382..4521c2f62c4 100644 --- a/src/gui/kernel/qpaintdevicewindow.cpp +++ b/src/gui/kernel/qpaintdevicewindow.cpp @@ -187,9 +187,6 @@ void QPaintDeviceWindow::exposeEvent(QExposeEvent *exposeEvent) // sometimes relative to the parent, depending on the platform plugin. // We require local coords here. d->doFlush(QRect(QPoint(0, 0), size())); - } else if (!d->dirtyRegion.isEmpty()) { - // Updates while non-exposed were ignored. Schedule an update now. - requestUpdate(); } } From ced4d167a25b63afd293a59aed389ca6efce7951 Mon Sep 17 00:00:00 2001 From: Mark Brand Date: Mon, 5 Sep 2016 18:05:43 +0200 Subject: [PATCH 76/87] fix -system-sqlite configure option Although configuration seemed to work and the configure summary indicated that the system sqlite library was being used, qtsql was actually still built from bundled sqlite sources. The problem was that system-sqlite was not reaching the context of sqlite.pro. Change-Id: I24676a19f0fc895111844cd0fe6c7e80f33574de Reviewed-by: Lars Knoll --- src/plugins/sqldrivers/sqlite/sqlite.pro | 8 +++++--- src/sql/configure.json | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/plugins/sqldrivers/sqlite/sqlite.pro b/src/plugins/sqldrivers/sqlite/sqlite.pro index bcdf7d36f32..1066bf7f51d 100644 --- a/src/plugins/sqldrivers/sqlite/sqlite.pro +++ b/src/plugins/sqldrivers/sqlite/sqlite.pro @@ -1,12 +1,14 @@ TARGET = qsqlite +QT_FOR_CONFIG += sql-private + HEADERS += $$PWD/qsql_sqlite_p.h SOURCES += $$PWD/qsql_sqlite.cpp $$PWD/smain.cpp -!system-sqlite { - include($$PWD/../../../3rdparty/sqlite.pri) -} else { +qtConfig(system-sqlite) { QMAKE_USE += sqlite +} else { + include($$PWD/../../../3rdparty/sqlite.pri) } OTHER_FILES += sqlite.json diff --git a/src/sql/configure.json b/src/sql/configure.json index d1dc1986567..5476d419ed1 100644 --- a/src/sql/configure.json +++ b/src/sql/configure.json @@ -170,7 +170,7 @@ "label": " Using system provided SQLite", "autoDetect": false, "condition": "features.sql-sqlite && libs.sqlite3", - "output": [ "publicQtConfig" ] + "output": [ "privateFeature" ] }, "sql-tds": { "label": "TDS (Sybase)", From a41393d0bc05998a7de2dcf872953b6d24b71e96 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Fri, 19 Aug 2016 09:00:37 +0200 Subject: [PATCH 77/87] QColor: clean up qcolor_p.h Only qt_get_hex_rgb(const char*, QRgb*) is used outside qcolor.cpp (in qxpmhandler.cpp), so remove all other function declarations from qcolor_p.h, and make the functions file-static in qcolor.cpp, removing their qt_ prefix to avoid confusion. Exception: it turned out that qt_get_named_rgb(const char *, QRgb*) wasn't actually used anywhere, but a follow-up commit will fix this. Adjust interface to that of the QChar overload (add explicit int len). Simplify conditional compilation of QT_NO_COLORNAMES: move the ifdef inside get_colornames, to avoid duplicating the declaration, and remove the empty implementation of get_named_rgb, since their use is already conditional on QT_NO_COLORNAMES not being defined. Change-Id: Iaf685dfbea0b9d3bd010448dac0e95be7b097ce5 Reviewed-by: Edward Welbourne --- src/gui/painting/qcolor.cpp | 59 ++++++++++++++++--------------------- src/gui/painting/qcolor_p.h | 5 ---- 2 files changed, 25 insertions(+), 39 deletions(-) diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp index 650ba0187ed..5f971599d26 100644 --- a/src/gui/painting/qcolor.cpp +++ b/src/gui/painting/qcolor.cpp @@ -79,12 +79,12 @@ static inline int hex2int(char s) return h < 0 ? h : (h << 4) | h; } -bool qt_get_hex_rgb(const char *name, QRgb *rgb) +static bool get_hex_rgb(const char *name, int len, QRgb *rgb) { if (name[0] != '#') return false; name++; - int len = qstrlen(name); + --len; int a, r, g, b; a = 255; if (len == 12) { @@ -119,15 +119,19 @@ bool qt_get_hex_rgb(const char *name, QRgb *rgb) return true; } -bool qt_get_hex_rgb(const QChar *str, int len, QRgb *rgb) +bool qt_get_hex_rgb(const char *name, QRgb *rgb) +{ + return get_hex_rgb(name, qstrlen(name), rgb); +} + +static bool get_hex_rgb(const QChar *str, int len, QRgb *rgb) { if (len > 13) return false; char tmp[16]; for (int i = 0; i < len; ++i) tmp[i] = str[i].toLatin1(); - tmp[len] = 0; - return qt_get_hex_rgb(tmp, rgb); + return get_hex_rgb(tmp, len, rgb); } #ifndef QT_NO_COLORNAMES @@ -309,7 +313,7 @@ inline bool operator<(const char *name, const RGBData &data) inline bool operator<(const RGBData &data, const char *name) { return qstrcmp(data.name, name) < 0; } -static bool get_named_rgb(const char *name_no_space, QRgb *rgb) +static bool get_named_rgb_no_space(const char *name_no_space, QRgb *rgb) { const RGBData *r = std::lower_bound(rgbTbl, rgbTbl + rgbTblSize, name_no_space); if ((r != rgbTbl + rgbTblSize) && !(name_no_space < *r)) { @@ -319,9 +323,9 @@ static bool get_named_rgb(const char *name_no_space, QRgb *rgb) return false; } -bool qt_get_named_rgb(const char *name, QRgb* rgb) +#ifdef QCOLOR_THIS_IS_CURRENTLY_UNUSED_BUT_WILL_BE_USED_SOON +static bool get_named_rgb(const char *name, int len, QRgb* rgb) { - int len = int(strlen(name)); if (len > 255) return false; char name_no_space[256]; @@ -332,10 +336,11 @@ bool qt_get_named_rgb(const char *name, QRgb* rgb) } name_no_space[pos] = 0; - return get_named_rgb(name_no_space, rgb); + return get_named_rgb_no_space(name_no_space, rgb); } +#endif -bool qt_get_named_rgb(const QChar *name, int len, QRgb *rgb) +static bool get_named_rgb(const QChar *name, int len, QRgb *rgb) { if (len > 255) return false; @@ -346,32 +351,22 @@ bool qt_get_named_rgb(const QChar *name, int len, QRgb *rgb) name_no_space[pos++] = name[i].toLower().toLatin1(); } name_no_space[pos] = 0; - return get_named_rgb(name_no_space, rgb); + return get_named_rgb_no_space(name_no_space, rgb); } -QStringList qt_get_colornames() +#endif // QT_NO_COLORNAMES + +static QStringList get_colornames() { - int i = 0; QStringList lst; +#ifndef QT_NO_COLORNAMES lst.reserve(rgbTblSize); - for (i = 0; i < rgbTblSize; i++) + for (int i = 0; i < rgbTblSize; i++) lst << QLatin1String(rgbTbl[i].name); +#endif return lst; } -#else - -bool qt_get_named_rgb(const char *, QRgb*) -{ - return false; -} - -QStringList qt_get_colornames() -{ - return QStringList(); -} -#endif // QT_NO_COLORNAMES - /*! \class QColor \brief The QColor class provides colors based on RGB, HSV or CMYK values. @@ -911,7 +906,7 @@ bool QColor::setColorFromString(const QString &name) if (name.startsWith(QLatin1Char('#'))) { QRgb rgba; - if (qt_get_hex_rgb(name.constData(), name.length(), &rgba)) { + if (get_hex_rgb(name.constData(), name.length(), &rgba)) { setRgba(rgba); return true; } else { @@ -922,7 +917,7 @@ bool QColor::setColorFromString(const QString &name) #ifndef QT_NO_COLORNAMES QRgb rgb; - if (qt_get_named_rgb(name.constData(), name.length(), &rgb)) { + if (get_named_rgb(name.constData(), name.length(), &rgb)) { setRgba(rgb); return true; } else @@ -940,11 +935,7 @@ bool QColor::setColorFromString(const QString &name) */ QStringList QColor::colorNames() { -#ifndef QT_NO_COLORNAMES - return qt_get_colornames(); -#else - return QStringList(); -#endif + return get_colornames(); } /*! diff --git a/src/gui/painting/qcolor_p.h b/src/gui/painting/qcolor_p.h index b5e92e2ea2f..b44f2b163aa 100644 --- a/src/gui/painting/qcolor_p.h +++ b/src/gui/painting/qcolor_p.h @@ -53,15 +53,10 @@ #include #include "QtGui/qrgb.h" -#include "QtCore/qstringlist.h" QT_BEGIN_NAMESPACE -bool qt_get_named_rgb(const char *, QRgb*); -bool qt_get_named_rgb(const QChar *, int len, QRgb*); bool qt_get_hex_rgb(const char *, QRgb *); -bool qt_get_hex_rgb(const QChar *, int len, QRgb *); -QStringList qt_get_colornames(); QT_END_NAMESPACE From ceb3c2ea621a5c5542eb6d127625a934b865e869 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 16 Aug 2016 15:33:18 +0200 Subject: [PATCH 78/87] QXmlAttributes: re-enable suppressed move special member functions ... at least for compilers that support defaulting functions. The class is polymorphic, but shouldn't, so add a note to remove the vtable in Qt 6. Change-Id: I93e4402004b7c52ba506946220e214dd6990f1f7 Reviewed-by: Lars Knoll Reviewed-by: Thiago Macieira --- src/xml/sax/qxml.h | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/xml/sax/qxml.h b/src/xml/sax/qxml.h index 4af664d2dd7..ee608230038 100644 --- a/src/xml/sax/qxml.h +++ b/src/xml/sax/qxml.h @@ -116,7 +116,16 @@ class Q_XML_EXPORT QXmlAttributes { public: QXmlAttributes(); - virtual ~QXmlAttributes(); +#ifdef Q_COMPILER_DEFAULT_MEMBERS + QXmlAttributes(const QXmlAttributes &) = default; + QXmlAttributes(QXmlAttributes &&) Q_DECL_NOTHROW = default; + QXmlAttributes &operator=(const QXmlAttributes &) = default; + QXmlAttributes &operator=(QXmlAttributes &&) Q_DECL_NOTHROW = default; +#endif // default members +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + virtual // ### Qt 6: this value class don't need no virtual dtor +#endif + ~QXmlAttributes(); int index(const QString& qName) const; int index(QLatin1String qName) const; From 0889e9da20b8f016795ec2e7352b1e2f1678098d Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Fri, 19 Aug 2016 09:48:14 +0200 Subject: [PATCH 79/87] QColor: provide QLatin1String overloads of functions taking QString The inefficiency of QColor(const char*) came to light by a recent refactoring which showed that the existing char* overload of qt_get_hex_rgb() was never called. So, provide a QLatin1String interface for named colors that allows user code to reach that internal function without converting to QString first. Change-Id: I74df7b570ef28c00e35ca4adf46c4b7c7e9994b3 Reviewed-by: Edward Welbourne Reviewed-by: Anton Kudryavtsev --- src/gui/painting/qcolor.cpp | 44 ++++++++++++----- src/gui/painting/qcolor.h | 13 +++-- tests/auto/gui/painting/qcolor/tst_qcolor.cpp | 48 ++++++++++++++----- 3 files changed, 77 insertions(+), 28 deletions(-) diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp index 5f971599d26..05790c45043 100644 --- a/src/gui/painting/qcolor.cpp +++ b/src/gui/painting/qcolor.cpp @@ -323,7 +323,6 @@ static bool get_named_rgb_no_space(const char *name_no_space, QRgb *rgb) return false; } -#ifdef QCOLOR_THIS_IS_CURRENTLY_UNUSED_BUT_WILL_BE_USED_SOON static bool get_named_rgb(const char *name, int len, QRgb* rgb) { if (len > 255) @@ -338,7 +337,6 @@ static bool get_named_rgb(const char *name, int len, QRgb* rgb) return get_named_rgb_no_space(name_no_space, rgb); } -#endif static bool get_named_rgb(const QChar *name, int len, QRgb *rgb) { @@ -796,12 +794,14 @@ QColor::QColor(Spec spec) Q_DECL_NOTHROW /*! \fn QColor::QColor(const char *name) + \overload + \sa setNamedColor(), name(), isValid() +*/ - Constructs a named color in the same way as setNamedColor() using - the given \a name. - - The color is left invalid if the \a name cannot be parsed. - +/*! + \fn QColor::QColor(QLatin1String name) + \overload + \since 5.8 \sa setNamedColor(), name(), isValid() */ @@ -881,6 +881,16 @@ void QColor::setNamedColor(const QString &name) setColorFromString(name); } +/*! + \overload + \since 5.8 +*/ + +void QColor::setNamedColor(QLatin1String name) +{ + setColorFromString(name); +} + /*! \since 4.7 @@ -897,16 +907,26 @@ bool QColor::isValidColor(const QString &name) return !name.isEmpty() && QColor().setColorFromString(name); } -bool QColor::setColorFromString(const QString &name) +/*! + \overload + \since 5.8 +*/ +bool QColor::isValidColor(QLatin1String name) Q_DECL_NOTHROW { - if (name.isEmpty()) { + return name.size() && QColor().setColorFromString(name); +} + +template +bool QColor::setColorFromString(const String &name) +{ + if (!name.size()) { invalidate(); return true; } - if (name.startsWith(QLatin1Char('#'))) { + if (name[0] == QLatin1Char('#')) { QRgb rgba; - if (get_hex_rgb(name.constData(), name.length(), &rgba)) { + if (get_hex_rgb(name.data(), name.size(), &rgba)) { setRgba(rgba); return true; } else { @@ -917,7 +937,7 @@ bool QColor::setColorFromString(const QString &name) #ifndef QT_NO_COLORNAMES QRgb rgb; - if (get_named_rgb(name.constData(), name.length(), &rgb)) { + if (get_named_rgb(name.data(), name.size(), &rgb)) { setRgba(rgb); return true; } else diff --git a/src/gui/painting/qcolor.h b/src/gui/painting/qcolor.h index 6cf3a8e262d..db6eb92916f 100644 --- a/src/gui/painting/qcolor.h +++ b/src/gui/painting/qcolor.h @@ -73,7 +73,8 @@ public: QColor(QRgb rgb) Q_DECL_NOTHROW; QColor(QRgba64 rgba64) Q_DECL_NOTHROW; QColor(const QString& name); - QColor(const char *name); + QColor(const char *aname) : QColor(QLatin1String(aname)) {} + QColor(QLatin1String name); QColor(Spec spec) Q_DECL_NOTHROW; #if QT_VERSION < QT_VERSION_CHECK(6,0,0) @@ -93,7 +94,9 @@ public: // ### Qt 6: merge overloads QString name() const; QString name(NameFormat format) const; + void setNamedColor(const QString& name); + void setNamedColor(QLatin1String name); static QStringList colorNames(); @@ -219,11 +222,13 @@ public: operator QVariant() const; static bool isValidColor(const QString &name); + static bool isValidColor(QLatin1String) Q_DECL_NOTHROW; private: void invalidate() Q_DECL_NOTHROW; - bool setColorFromString(const QString &name); + template + bool setColorFromString(const String &name); Spec cspec; union { @@ -272,8 +277,8 @@ inline QColor::QColor() Q_DECL_NOTHROW inline QColor::QColor(int r, int g, int b, int a) { setRgb(r, g, b, a); } -inline QColor::QColor(const char *aname) -{ setNamedColor(QLatin1String(aname)); } +inline QColor::QColor(QLatin1String aname) +{ setNamedColor(aname); } inline QColor::QColor(const QString& aname) { setNamedColor(aname); } diff --git a/tests/auto/gui/painting/qcolor/tst_qcolor.cpp b/tests/auto/gui/painting/qcolor/tst_qcolor.cpp index 00e7436c0f3..ab893385e39 100644 --- a/tests/auto/gui/painting/qcolor/tst_qcolor.cpp +++ b/tests/auto/gui/painting/qcolor/tst_qcolor.cpp @@ -52,6 +52,7 @@ private slots: void name(); void namehex_data(); void namehex(); + void setNamedColor_data(); void setNamedColor(); void constructNamedColorWithSpace(); @@ -525,26 +526,49 @@ static const int rgbTblSize = sizeof(rgbTbl) / sizeof(RGBData); #undef rgb -void tst_QColor::setNamedColor() +void tst_QColor::setNamedColor_data() { - for (int i = 0; i < rgbTblSize; ++i) { + QTest::addColumn("byCtor"); + QTest::addColumn("bySetNamedColor"); + QTest::addColumn("expected"); + + for (const auto e : rgbTbl) { QColor expected; - expected.setRgba(rgbTbl[i].value); + expected.setRgba(e.value); - QColor color; - color.setNamedColor(QLatin1String(rgbTbl[i].name)); - QCOMPARE(color, expected); +#define ROW(expr) \ + do { \ + QColor bySetNamedColor; \ + bySetNamedColor.setNamedColor(expr); \ + auto byCtor = QColor(expr); \ + QTest::newRow(e.name + QByteArrayLiteral(#expr)) \ + << byCtor << bySetNamedColor << expected; \ + } while (0) \ + /*end*/ + ROW(QLatin1String(e.name)); + ROW(QString(QLatin1String(e.name))); // name should be case insensitive - color.setNamedColor(QString(rgbTbl[i].name).toUpper()); - QCOMPARE(color, expected); - + ROW(QLatin1String(QByteArray(e.name).toUpper())); + ROW(QString(e.name).toUpper()); // spaces should be ignored - color.setNamedColor(QString(rgbTbl[i].name).insert(1, ' ')); - QCOMPARE(color, expected); + ROW(QLatin1String(QByteArray(e.name).insert(1, ' '))); + ROW(QString(e.name).insert(1, ' ')); +#undef ROW } } +void tst_QColor::setNamedColor() +{ + QFETCH(QColor, byCtor); + QFETCH(QColor, bySetNamedColor); + QFETCH(QColor, expected); + + QCOMPARE(byCtor, expected); + QCOMPARE(bySetNamedColor, expected); +} + + void tst_QColor::constructNamedColorWithSpace() { QColor whiteSmoke("white smoke"); @@ -556,7 +580,7 @@ void tst_QColor::colorNames() QStringList all = QColor::colorNames(); QCOMPARE(all.size(), rgbTblSize); for (int i = 0; i < all.size(); ++i) - QCOMPARE(all.at(i), QString::fromLatin1(rgbTbl[i].name)); + QCOMPARE(all.at(i), QLatin1String(rgbTbl[i].name)); } void tst_QColor::spec() From 9888a2c138c675c5f83ec4d4b8aeac075bc12009 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Fri, 23 Sep 2016 07:42:48 +0200 Subject: [PATCH 80/87] Fix test for WinRT Only on win32 we can omit creating a new window. Change-Id: Ie49ef45ccb745aaa43f58096e7810c71671124ba Reviewed-by: Oliver Wolff --- tests/auto/gui/util/qdesktopservices/tst_qdesktopservices.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/gui/util/qdesktopservices/tst_qdesktopservices.cpp b/tests/auto/gui/util/qdesktopservices/tst_qdesktopservices.cpp index f57ed12ed33..add23d46cfa 100644 --- a/tests/auto/gui/util/qdesktopservices/tst_qdesktopservices.cpp +++ b/tests/auto/gui/util/qdesktopservices/tst_qdesktopservices.cpp @@ -46,7 +46,7 @@ void tst_qdesktopservices::openUrl() { // At the bare minimum check that they return false for invalid url's QCOMPARE(QDesktopServices::openUrl(QUrl()), false); -#if defined(Q_OS_WIN) +#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) // this test is only valid on windows on other systems it might mean open a new document in the application handling .file const QRegularExpression messagePattern("ShellExecute 'file://invalid\\.file' failed \\(error \\d+\\)\\."); QVERIFY(messagePattern.isValid()); From 31b3986e2dfc962e271a74fa43333c4621e3bd50 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Tue, 20 Sep 2016 16:29:58 +0200 Subject: [PATCH 81/87] Fix DirectWrite engine when loading from data through QRawFont The stretch, once it is passed to the font engine, is assumed to be the horizontal scale needed to match the requested stretch for the given font. When loading from data in QRawFont, there is no way to specify this stretch; the scale should always be 1. The effect of this was that when DirectWrite was backing a font loaded through QRawFont directly from data, then the glyph images would be scaled to 0xHEIGHT before they were returned, thus they would be empty. This was a regression caused by ec7fee968f5f1a842b7d2fe670de1d517ecca308. Task-number: QTBUG-56091 Change-Id: I38e76e0e8f6809262474922946752b2ad0d6209b Reviewed-by: Konstantin Ritt Reviewed-by: Friedemann Kleint --- src/plugins/platforms/windows/qwindowsfontdatabase.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp index 04b95308904..d667036e8a6 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp @@ -1257,6 +1257,7 @@ QT_WARNING_POP request.pixelSize = pixelSize; request.styleStrategy = QFont::PreferMatch; request.hintingPreference = hintingPreference; + request.stretch = QFont::Unstretched; fontEngine = QWindowsFontDatabase::createEngine(request, QWindowsContext::instance()->defaultDPI(), From 0be620ac58d43d2ad977944682b24ef1df3c21e0 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Thu, 22 Sep 2016 15:01:55 +0200 Subject: [PATCH 82/87] Fix test for targets without process support There is no need to switch to the current directory, when there is no process support. This also fixes running the test on sandboxed target platforms. Change-Id: I25fabb8b22d3510062a012884eb1eaab682901d3 Reviewed-by: Oliver Wolff --- tests/auto/gui/kernel/qclipboard/tst_qclipboard.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/auto/gui/kernel/qclipboard/tst_qclipboard.cpp b/tests/auto/gui/kernel/qclipboard/tst_qclipboard.cpp index bfa15744c2b..b1ec94403aa 100644 --- a/tests/auto/gui/kernel/qclipboard/tst_qclipboard.cpp +++ b/tests/auto/gui/kernel/qclipboard/tst_qclipboard.cpp @@ -73,8 +73,10 @@ void tst_QClipboard::cleanupTestCase() void tst_QClipboard::init() { +#ifndef QT_NO_PROCESS const QString testdataDir = QFileInfo(QFINDTESTDATA("copier")).absolutePath(); QVERIFY2(QDir::setCurrent(testdataDir), qPrintable("Could not chdir to " + testdataDir)); +#endif } Q_DECLARE_METATYPE(QClipboard::Mode) From c1b1e58de8be4d012b93d78e0ce2712b3b802d1a Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Fri, 19 Aug 2016 10:09:50 +0200 Subject: [PATCH 83/87] QGuiVariant: use new QColor::setNamedColor(QLatin1String) Change-Id: If36f9f3c60ee5cea3082a973a4b8ea9d2de1b62f Reviewed-by: Edward Welbourne --- src/gui/kernel/qguivariant.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/gui/kernel/qguivariant.cpp b/src/gui/kernel/qguivariant.cpp index 4ae4b209cac..bde0d20ea8b 100644 --- a/src/gui/kernel/qguivariant.cpp +++ b/src/gui/kernel/qguivariant.cpp @@ -260,8 +260,7 @@ static bool convert(const QVariant::Private *d, int t, static_cast(result)->setNamedColor(*v_cast(d)); return static_cast(result)->isValid(); } else if (d->type == QVariant::ByteArray) { - static_cast(result)->setNamedColor(QString::fromLatin1( - *v_cast(d))); + static_cast(result)->setNamedColor(QLatin1String(*v_cast(d))); return true; } else if (d->type == QVariant::Brush) { if (v_cast(d)->style() == Qt::SolidPattern) { From eeb03fbf262e2a4790579c2100930799b0866057 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Mon, 19 Sep 2016 12:09:53 +0200 Subject: [PATCH 84/87] Deduplication fetchTransformed Unify generic and ARGB32PM versions for fetchTransformed, the main benefit of the specialized version is the simplified fetch, but we can also get that by ensuring the method can be inlined. At the same time move runtime inline of fetchPixel in fetchTransformedBilinear to compile time using a similar model. Change-Id: I0c1ed2ea4d4a3fb1b6dd3973823c0925101ed18e Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/gui/painting/qdrawhelper.cpp | 185 ++++++++----------------------- 1 file changed, 48 insertions(+), 137 deletions(-) diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index c1a49b7d9a1..7685f7f4ca2 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -836,7 +836,10 @@ static const uint *QT_FASTCALL convertGrayscale8FromARGB32PM(uint *buffer, const } template static -uint QT_FASTCALL fetchPixel(const uchar *src, int index); +uint QT_FASTCALL fetchPixel(const uchar *, int) +{ + Q_UNREACHABLE(); +} template <> inline uint QT_FASTCALL fetchPixel(const uchar *src, int index) @@ -1554,92 +1557,11 @@ static const QRgba64 *QT_FASTCALL fetchUntransformed64(QRgba64 *buffer, const Op } } -// blendType is either BlendTransformed or BlendTransformedTiled -template -static const uint *QT_FASTCALL fetchTransformedARGB32PM(uint *buffer, const Operator *, const QSpanData *data, - int y, int x, int length) -{ - int image_width = data->texture.width; - int image_height = data->texture.height; - - const qreal cx = x + qreal(0.5); - const qreal cy = y + qreal(0.5); - - const uint *end = buffer + length; - uint *b = buffer; - if (data->fast_matrix) { - // The increment pr x in the scanline - int fdx = (int)(data->m11 * fixed_scale); - int fdy = (int)(data->m12 * fixed_scale); - - int fx = int((data->m21 * cy - + data->m11 * cx + data->dx) * fixed_scale); - int fy = int((data->m22 * cy - + data->m12 * cx + data->dy) * fixed_scale); - - while (b < end) { - int px = fx >> 16; - int py = fy >> 16; - - if (blendType == BlendTransformedTiled) { - px %= image_width; - py %= image_height; - if (px < 0) px += image_width; - if (py < 0) py += image_height; - } else { - px = qBound(0, px, image_width - 1); - py = qBound(0, py, image_height - 1); - } - *b = reinterpret_cast(data->texture.scanLine(py))[px]; - - fx += fdx; - fy += fdy; - ++b; - } - } else { - const qreal fdx = data->m11; - const qreal fdy = data->m12; - const qreal fdw = data->m13; - - qreal fx = data->m21 * cy + data->m11 * cx + data->dx; - qreal fy = data->m22 * cy + data->m12 * cx + data->dy; - qreal fw = data->m23 * cy + data->m13 * cx + data->m33; - - while (b < end) { - const qreal iw = fw == 0 ? 1 : 1 / fw; - const qreal tx = fx * iw; - const qreal ty = fy * iw; - int px = int(tx) - (tx < 0); - int py = int(ty) - (ty < 0); - - if (blendType == BlendTransformedTiled) { - px %= image_width; - py %= image_height; - if (px < 0) px += image_width; - if (py < 0) py += image_height; - } else { - px = qBound(0, px, image_width - 1); - py = qBound(0, py, image_height - 1); - } - *b = reinterpret_cast(data->texture.scanLine(py))[px]; - - fx += fdx; - fy += fdy; - fw += fdw; - //force increment to avoid /0 - if (!fw) { - fw += fdw; - } - ++b; - } - } - return buffer; -} - -template /* either BlendTransformed or BlendTransformedTiled */ +template static const uint *QT_FASTCALL fetchTransformed(uint *buffer, const Operator *, const QSpanData *data, int y, int x, int length) { + Q_STATIC_ASSERT(blendType == BlendTransformed || blendType == BlendTransformedTiled); int image_width = data->texture.width; int image_height = data->texture.height; @@ -1647,9 +1569,12 @@ static const uint *QT_FASTCALL fetchTransformed(uint *buffer, const Operator *, const qreal cy = y + qreal(0.5); const QPixelLayout *layout = &qPixelLayouts[data->texture.format]; - FetchPixelFunc fetch = qFetchPixel[layout->bpp]; + if (bpp != QPixelLayout::BPPNone) // Like this to not ICE on GCC 5.3.1 + Q_ASSERT(layout->bpp == bpp); + // When templated 'fetch' should be inlined at compile time: + const FetchPixelFunc fetch = (bpp == QPixelLayout::BPPNone) ? qFetchPixel[layout->bpp] : fetchPixel; - const uint *end = buffer + length; + uint *const end = buffer + length; uint *b = buffer; if (data->fast_matrix) { // The increment pr x in the scanline @@ -2585,12 +2510,17 @@ static const uint * QT_FASTCALL fetchTransformedBilinearARGB32PM(uint *buffer, c } // blendType = BlendTransformedBilinear or BlendTransformedBilinearTiled -template +template static const uint *QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator *, const QSpanData *data, int y, int x, int length) { const QPixelLayout *layout = &qPixelLayouts[data->texture.format]; const QVector *clut = data->texture.colorTable; + if (bpp != QPixelLayout::BPPNone) // Like this to not ICE on GCC 5.3.1 + Q_ASSERT(layout->bpp == bpp); + // When templated 'fetch' should be inlined at compile time: + const FetchPixelsFunc fetch = (bpp == QPixelLayout::BPPNone) ? qFetchPixels[layout->bpp] : fetchPixels; + const FetchPixelFunc fetch1 = (bpp == QPixelLayout::BPPNone) ? qFetchPixel[layout->bpp] : fetchPixel; int image_width = data->texture.width; int image_height = data->texture.height; @@ -2628,7 +2558,6 @@ static const uint *QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Oper // The idea is first to do the interpolation between the row s1 and the row s2 // into an intermediate buffer, then we interpolate between two pixel of this buffer. - FetchPixelsFunc fetch = qFetchPixels[layout->bpp]; // +1 for the last pixel to interpolate with, and +1 for rounding errors. uint buf1[buffer_size + 2]; uint buf2[buffer_size + 2]; @@ -2717,7 +2646,6 @@ static const uint *QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Oper fx += fdx; } } else { - FetchPixelFunc fetch = qFetchPixel[layout->bpp]; uint buf1[buffer_size]; uint buf2[buffer_size]; uint *b = buffer; @@ -2728,19 +2656,10 @@ static const uint *QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Oper int x1 = (fx >> 16); int x2; fetchTransformedBilinear_pixelBounds(image_width, image_x1, image_x2, x1, x2); - - if (layout->bpp == QPixelLayout::BPP32) { - buf1[i * 2 + 0] = ((const uint*)s1)[x1]; - buf1[i * 2 + 1] = ((const uint*)s1)[x2]; - buf2[i * 2 + 0] = ((const uint*)s2)[x1]; - buf2[i * 2 + 1] = ((const uint*)s2)[x2]; - } else { - buf1[i * 2 + 0] = fetch(s1, x1); - buf1[i * 2 + 1] = fetch(s1, x2); - buf2[i * 2 + 0] = fetch(s2, x1); - buf2[i * 2 + 1] = fetch(s2, x2); - } - + buf1[i * 2 + 0] = fetch1(s1, x1); + buf1[i * 2 + 1] = fetch1(s1, x2); + buf2[i * 2 + 0] = fetch1(s2, x1); + buf2[i * 2 + 1] = fetch1(s2, x2); fx += fdx; } layout->convertToARGB32PM(buf1, buf1, len * 2, clut, 0); @@ -2770,7 +2689,6 @@ static const uint *QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Oper } } } else { //rotation - FetchPixelFunc fetch = qFetchPixel[layout->bpp]; uint buf1[buffer_size]; uint buf2[buffer_size]; uint *b = buffer; @@ -2789,19 +2707,10 @@ static const uint *QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Oper const uchar *s1 = data->texture.scanLine(y1); const uchar *s2 = data->texture.scanLine(y2); - - if (layout->bpp == QPixelLayout::BPP32) { - buf1[i * 2 + 0] = ((const uint*)s1)[x1]; - buf1[i * 2 + 1] = ((const uint*)s1)[x2]; - buf2[i * 2 + 0] = ((const uint*)s2)[x1]; - buf2[i * 2 + 1] = ((const uint*)s2)[x2]; - } else { - buf1[i * 2 + 0] = fetch(s1, x1); - buf1[i * 2 + 1] = fetch(s1, x2); - buf2[i * 2 + 0] = fetch(s2, x1); - buf2[i * 2 + 1] = fetch(s2, x2); - } - + buf1[i * 2 + 0] = fetch1(s1, x1); + buf1[i * 2 + 1] = fetch1(s1, x2); + buf2[i * 2 + 0] = fetch1(s2, x1); + buf2[i * 2 + 1] = fetch1(s2, x2); fx += fdx; fy += fdy; } @@ -2848,7 +2757,6 @@ static const uint *QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Oper qreal fy = data->m22 * cy + data->m12 * cx + data->dy; qreal fw = data->m23 * cy + data->m13 * cx + data->m33; - FetchPixelFunc fetch = qFetchPixel[layout->bpp]; uint buf1[buffer_size]; uint buf2[buffer_size]; uint *b = buffer; @@ -2876,18 +2784,10 @@ static const uint *QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Oper const uchar *s1 = data->texture.scanLine(y1); const uchar *s2 = data->texture.scanLine(y2); - - if (layout->bpp == QPixelLayout::BPP32) { - buf1[i * 2 + 0] = ((const uint*)s1)[x1]; - buf1[i * 2 + 1] = ((const uint*)s1)[x2]; - buf2[i * 2 + 0] = ((const uint*)s2)[x1]; - buf2[i * 2 + 1] = ((const uint*)s2)[x2]; - } else { - buf1[i * 2 + 0] = fetch(s1, x1); - buf1[i * 2 + 1] = fetch(s1, x2); - buf2[i * 2 + 0] = fetch(s2, x1); - buf2[i * 2 + 1] = fetch(s2, x2); - } + buf1[i * 2 + 0] = fetch1(s1, x1); + buf1[i * 2 + 1] = fetch1(s1, x2); + buf2[i * 2 + 0] = fetch1(s2, x1); + buf2[i * 2 + 1] = fetch1(s2, x2); fx += fdx; fy += fdy; @@ -3293,23 +3193,32 @@ static SourceFetchProc sourceFetchUntransformed[QImage::NImageFormats] = { }; static const SourceFetchProc sourceFetchGeneric[NBlendTypes] = { - fetchUntransformed, // Untransformed - fetchUntransformed, // Tiled - fetchTransformed, // Transformed - fetchTransformed, // TransformedTiled - fetchTransformedBilinear, // Bilinear - fetchTransformedBilinear // BilinearTiled + fetchUntransformed, // Untransformed + fetchUntransformed, // Tiled + fetchTransformed, // Transformed + fetchTransformed, // TransformedTiled + fetchTransformedBilinear, // TransformedBilinear + fetchTransformedBilinear // TransformedBilinearTiled }; static SourceFetchProc sourceFetchARGB32PM[NBlendTypes] = { fetchUntransformedARGB32PM, // Untransformed fetchUntransformedARGB32PM, // Tiled - fetchTransformedARGB32PM, // Transformed - fetchTransformedARGB32PM, // TransformedTiled + fetchTransformed, // Transformed + fetchTransformed, // TransformedTiled fetchTransformedBilinearARGB32PM, // Bilinear fetchTransformedBilinearARGB32PM // BilinearTiled }; +static SourceFetchProc sourceFetchAny32[NBlendTypes] = { + fetchUntransformed, // Untransformed + fetchUntransformed, // Tiled + fetchTransformed, // Transformed + fetchTransformed, // TransformedTiled + fetchTransformedBilinear, // TransformedBilinear + fetchTransformedBilinear // TransformedBilinearTiled +}; + static const SourceFetchProc64 sourceFetchGeneric64[NBlendTypes] = { fetchUntransformed64, // Untransformed fetchUntransformed64, // Tiled @@ -3325,6 +3234,8 @@ static inline SourceFetchProc getSourceFetch(TextureBlendType blendType, QImage: return sourceFetchARGB32PM[blendType]; if (blendType == BlendUntransformed || blendType == BlendTiled) return sourceFetchUntransformed[format]; + if (qPixelLayouts[format].bpp == QPixelLayout::BPP32) + return sourceFetchAny32[blendType]; return sourceFetchGeneric[blendType]; } From 8f71182d154cbf9ae202b154ab6f1d77b1615e20 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 23 Sep 2016 09:58:59 +0200 Subject: [PATCH 85/87] Enable building of qlalr with QT_NO_CAST_FROM/TO_ASCII Change-Id: I1b26c4b3ca84e0bb8001ca24ef46bd24926a0f82 Reviewed-by: Oswald Buddenhagen --- src/tools/qlalr/lalr.cpp | 2 +- src/tools/qlalr/lalr.h | 1 + src/tools/qlalr/main.cpp | 2 +- src/tools/qlalr/recognizer.cpp | 6 ++++-- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/tools/qlalr/lalr.cpp b/src/tools/qlalr/lalr.cpp index 81975a0f2ac..0ccf4c1588d 100644 --- a/src/tools/qlalr/lalr.cpp +++ b/src/tools/qlalr/lalr.cpp @@ -187,7 +187,7 @@ Grammar::Grammar (): tk_end = intern ("$end"); terminals.insert (tk_end); - spells.insert (tk_end, "end of file"); + spells.insert (tk_end, QLatin1String("end of file")); /*tk_error= terminals.insert (intern ("error"))*/; } diff --git a/src/tools/qlalr/lalr.h b/src/tools/qlalr/lalr.h index 28c889e63fb..b303b897d40 100644 --- a/src/tools/qlalr/lalr.h +++ b/src/tools/qlalr/lalr.h @@ -337,6 +337,7 @@ public: Grammar (); Name intern (const QString &id); + Name intern (const char *id) { return intern(QString::fromUtf8(id)); } inline bool isTerminal (Name name) const { return terminals.find (name) != terminals.end (); } diff --git a/src/tools/qlalr/main.cpp b/src/tools/qlalr/main.cpp index e16d5f1e8d0..c16bdcdf17e 100644 --- a/src/tools/qlalr/main.cpp +++ b/src/tools/qlalr/main.cpp @@ -65,7 +65,7 @@ int main (int argc, char *argv[]) bool no_lines = false; bool debug_info = true; bool qt_copyright = false; - QString file_name = 0; + QString file_name; const QStringList args = app.arguments().mid(1); for (const QString &arg : args) { diff --git a/src/tools/qlalr/recognizer.cpp b/src/tools/qlalr/recognizer.cpp index ca2551707e8..69dad1a6c18 100644 --- a/src/tools/qlalr/recognizer.cpp +++ b/src/tools/qlalr/recognizer.cpp @@ -178,7 +178,8 @@ int Recognizer::nextToken() text.clear (); if (! _M_no_lines) - text += QLatin1String ("\n#line ") + QString::number (_M_action_line) + " \"" + _M_input_file + "\"\n"; + text += QLatin1String("\n#line ") + QString::number (_M_action_line) + + QLatin1String(" \"") + _M_input_file + QLatin1String("\"\n"); inp (); // skip ':' forever @@ -215,7 +216,8 @@ int Recognizer::nextToken() text.clear (); if (! _M_no_lines) - text += QLatin1String ("\n#line ") + QString::number (_M_action_line) + " \"" + _M_input_file + "\"\n"; + text += QLatin1String ("\n#line ") + QString::number (_M_action_line) + + QLatin1String(" \"") + _M_input_file + QLatin1String("\"\n"); inp (); // skip ':' From 4d676acdc5968c9314bd16ac999ef3bbab4860b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Martins?= Date: Sat, 17 Sep 2016 18:39:48 +0100 Subject: [PATCH 86/87] Fix event names on comment about QChildEvent Change-Id: If9901471e459acb374807649e0affb84d82f7b8b Reviewed-by: David Faure Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/kernel/qobject.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index e901d8cefa1..63b02d2c0c1 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -222,7 +222,7 @@ QObjectPrivate::QObjectPrivate(int version) blockSig = false; // not blocking signals wasDeleted = false; // double-delete catcher isDeletingChildren = false; // set by deleteChildren() - sendChildEvents = true; // if we should send ChildInsert and ChildRemove events to parent + sendChildEvents = true; // if we should send ChildAdded and ChildRemoved events to parent receiveChildEvents = true; postedEvents = 0; extraData = 0; From 41a7d74385eece725435159ca021151e871bf116 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Thu, 22 Sep 2016 14:58:58 +0200 Subject: [PATCH 87/87] Document 3rd party source that is part of Qt Test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I8f324e23909232ee80a8d123fba35f5a6fecfaac Reviewed-by: Topi Reiniö --- src/testlib/3rdparty/CALLGRIND_LICENSE.txt | 35 ++ src/testlib/3rdparty/CYCLE_LICENSE.txt | 18 ++ src/testlib/3rdparty/LINUX_LICENSE.txt | 351 +++++++++++++++++++++ src/testlib/3rdparty/qt_attribution.json | 42 +++ src/testlib/doc/src/qttest-index.qdoc | 13 + 5 files changed, 459 insertions(+) create mode 100644 src/testlib/3rdparty/CALLGRIND_LICENSE.txt create mode 100644 src/testlib/3rdparty/CYCLE_LICENSE.txt create mode 100644 src/testlib/3rdparty/LINUX_LICENSE.txt create mode 100644 src/testlib/3rdparty/qt_attribution.json diff --git a/src/testlib/3rdparty/CALLGRIND_LICENSE.txt b/src/testlib/3rdparty/CALLGRIND_LICENSE.txt new file mode 100644 index 00000000000..0a6a7934226 --- /dev/null +++ b/src/testlib/3rdparty/CALLGRIND_LICENSE.txt @@ -0,0 +1,35 @@ + This file is part of callgrind, a valgrind tool for cache simulation + and call tree tracing. + + Copyright (C) 2003-2007 Josef Weidendorfer. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. The origin of this software must not be misrepresented; you must + not claim that you wrote the original software. If you use this + software in a product, an acknowledgment in the product + documentation would be appreciated but is not required. + + 3. Altered source versions must be plainly marked as such, and must + not be misrepresented as being the original software. + + 4. The name of the author may not be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/src/testlib/3rdparty/CYCLE_LICENSE.txt b/src/testlib/3rdparty/CYCLE_LICENSE.txt new file mode 100644 index 00000000000..c9b44cb8aae --- /dev/null +++ b/src/testlib/3rdparty/CYCLE_LICENSE.txt @@ -0,0 +1,18 @@ +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/src/testlib/3rdparty/LINUX_LICENSE.txt b/src/testlib/3rdparty/LINUX_LICENSE.txt new file mode 100644 index 00000000000..c0ff68a2b2a --- /dev/null +++ b/src/testlib/3rdparty/LINUX_LICENSE.txt @@ -0,0 +1,351 @@ + + NOTE! This copyright does *not* cover user programs that use kernel + services by normal system calls - this is merely considered normal use + of the kernel, and does *not* fall under the heading of "derived work". + Also note that the GPL below is copyrighted by the Free Software + Foundation, but the instance of code that it refers to (the linux + kernel) is copyrighted by me and others who actually wrote it. + + Linus Torvalds + +---------------------------------------- + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/src/testlib/3rdparty/qt_attribution.json b/src/testlib/3rdparty/qt_attribution.json new file mode 100644 index 00000000000..23d230cb5ca --- /dev/null +++ b/src/testlib/3rdparty/qt_attribution.json @@ -0,0 +1,42 @@ +[ + { + "Id": "callgrind", + "Name": "Callgrind", + "QDocModule": "qttestlib", + "QtUsage": "Used on Linux ond MacOS in the Qt Test module.", + + "Description": "callgrind_p.h is part of Valgrind: an instrumentation framework for building dynamic analysis tools.", + "Homepage": "http://valgrind.org/", + "License": "BSD 4-clause \"Original\" or \"Old\" License", + "LicenseId": "BSD-4-Clause", + "LicenseFile": "CALLGRIND_LICENSE.txt", + "Copyright": "Copyright (C) 2003-2007 Josef Weidendorfer. All rights reserved." + }, + { + "Id": "cycle", + "Name": "Cycle", + "QDocModule": "qttestlib", + "QtUsage": "Used in the Qt Test module.", + + "Description": "cycle_p.h allows to access the CPU's cycle counters.", + "License": "MIT License", + "LicenseId": "MIT", + "LicenseFile": "CYCLE_LICENSE.txt", + "Copyright": "Copyright (c) 2003, 2006 Matteo Frigo +Copyright (c) 2003, 2006 Massachusetts Institute of Technology" + }, + { + "Id": "linuxperf", + "Name": "Linux Performance Events", + "QDocModule": "qttestlib", + "QtUsage": "Used on Linux and Android in the Qt Test module.", + + "Description": "linux_perf_event_p.h allows access to the LInux kernel's performance events.", + "License": "GNU General Public License v2.0 only", + "LicenseId": "GPL-2.0", + "LicenseFile": "LINUX_LICENSE.txt", + "Copyright": "Copyright (C) 2008-2009, Thomas Gleixner +Copyright (C) 2008-2011, Red Hat, Inc., Ingo Molnar +Copyright (C) 2008-2011, Red Hat, Inc., Peter Zijlstra" + } +] diff --git a/src/testlib/doc/src/qttest-index.qdoc b/src/testlib/doc/src/qttest-index.qdoc index b16ab7944aa..36ebfee463b 100644 --- a/src/testlib/doc/src/qttest-index.qdoc +++ b/src/testlib/doc/src/qttest-index.qdoc @@ -50,6 +50,19 @@ \li \l{Qt Test Tutorial} \endlist + \section1 Licenses and Attributions + + Qt Test is available under commercial licenses from \l{The Qt Company}. + In addition, it is available under the + \l{GNU Lesser General Public License, version 3}, or + the \l{GNU General Public License, version 2}. + See \l{Qt Licensing} for further details. + + Furthermore Qt Test potentially contains third party + modules under following permissive licenses: + + \generatelist{groupsbymodule attributions-qttestlib} + \section1 Reference These are links to the API reference materials.