From 3fa18bf8816ccbbdf43eed2759c9a223cec039e8 Mon Sep 17 00:00:00 2001 From: Albert Astals Cid Date: Tue, 16 Aug 2016 11:42:42 +0200 Subject: [PATCH 01/24] Make sure connection is not null before using it connectionFromId can return null if the id isn't found. This causes crashes like http://paste.ubuntu.com/23061009/ Change-Id: Ib72412f61dc7661455394679b3e90662de505920 Reviewed-by: Lorn Potter --- src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp index 42037ffb9af..13b64a556c7 100644 --- a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp +++ b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp @@ -218,6 +218,10 @@ void QNetworkManagerEngine::disconnectFromId(const QString &id) QMutexLocker locker(&mutex); QNetworkManagerSettingsConnection *connection = connectionFromId(id); + + if (!connection) + return; + QNmSettingsMap map = connection->getSettings(); bool connectionAutoconnect = map.value("connection").value("autoconnect",true).toBool(); //if not present is true !! if (connectionAutoconnect) { //autoconnect connections will simply be reconnected by nm @@ -563,7 +567,7 @@ bool QNetworkManagerEngine::isConnectionActive(const QString &settingsPath) } QNetworkManagerSettingsConnection *settingsConnection = connectionFromId(settingsPath); - if (settingsConnection->getType() == DEVICE_TYPE_MODEM) { + if (settingsConnection && settingsConnection->getType() == DEVICE_TYPE_MODEM) { return isActiveContext(settingsConnection->path()); } From 449390c3a5f3a91e3895cbba0a583386e93366b7 Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Sun, 21 Aug 2016 22:49:35 +0300 Subject: [PATCH 02/24] Revert "QLocale: Actually get the language script for the system locale" The text direction should *not* be set by the default script, but by the UI direction. For example, if the default script is Hebrew, but the UI is in English, it doesn't make sense to default all the controls to RTL. This should be done only if the UI is RTL. This reverts commit a90869861cbc9927af2bbab5a94630e47b33fd5c. Task-number: QTBUG-53110 Change-Id: I5a6951ac30f24eec86bc0ae2a9fcfe14eb3a8e28 Reviewed-by: Olivier Goffart (Woboq GmbH) Reviewed-by: Thiago Macieira --- src/corelib/tools/qlocale_win.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/corelib/tools/qlocale_win.cpp b/src/corelib/tools/qlocale_win.cpp index a5eb7ec0589..7faf36b0892 100644 --- a/src/corelib/tools/qlocale_win.cpp +++ b/src/corelib/tools/qlocale_win.cpp @@ -841,7 +841,6 @@ QVariant QSystemLocale::query(QueryType type, QVariant in = QVariant()) const case ZeroDigit: return d->zeroDigit(); case LanguageId: - case ScriptId: case CountryId: { QString locale = QString::fromLatin1(getWinLocaleName()); QLocale::Language lang; @@ -850,12 +849,12 @@ QVariant QSystemLocale::query(QueryType type, QVariant in = QVariant()) const QLocalePrivate::getLangAndCountry(locale, lang, script, cntry); if (type == LanguageId) return lang; - if (type == ScriptId) - return script == QLocale::AnyScript ? fallbackUiLocale().script() : script; if (cntry == QLocale::AnyCountry) return fallbackUiLocale().country(); return cntry; } + case ScriptId: + return QVariant(QLocale::AnyScript); case MeasurementSystem: return d->measurementSystem(); case AMText: From 5e3f770ad5e47f296b4782c0b6c5b03162027500 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Str=C3=B8mme?= Date: Thu, 18 Aug 2016 11:44:45 +0200 Subject: [PATCH 03/24] Fix problem with exception reporting in QFuture::waitForResult() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes a problem that occurs when a task, that is run synchronously, throws an exception. If that happened, then the exception would not be re-thrown, because of an early return. Task-number: QTBUG-54831 Change-Id: Ic70c5b810ec6adce6e62bfd6832ba9f170b13a7f Reviewed-by: Jędrzej Nowacki --- src/corelib/thread/qfutureinterface.cpp | 11 +++--- .../qtconcurrentrun/tst_qtconcurrentrun.cpp | 37 +++++++++++++++++++ 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/src/corelib/thread/qfutureinterface.cpp b/src/corelib/thread/qfutureinterface.cpp index 60155c96fd6..2fe038165bf 100644 --- a/src/corelib/thread/qfutureinterface.cpp +++ b/src/corelib/thread/qfutureinterface.cpp @@ -299,12 +299,11 @@ void QFutureInterfaceBase::waitForResult(int resultIndex) lock.relock(); - if (!(d->state & Running)) - return; - - const int waitIndex = (resultIndex == -1) ? INT_MAX : resultIndex; - while ((d->state & Running) && d->internal_isResultReadyAt(waitIndex) == false) - d->waitCondition.wait(&d->m_mutex); + if (d->state & Running) { + const int waitIndex = (resultIndex == -1) ? INT_MAX : resultIndex; + while ((d->state & Running) && d->internal_isResultReadyAt(waitIndex) == false) + d->waitCondition.wait(&d->m_mutex); + } d->m_exceptionStore.throwPossibleException(); } diff --git a/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp b/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp index 8ffe4d8dfe2..7e057f3bcf4 100644 --- a/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp +++ b/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp @@ -440,6 +440,19 @@ int throwFunctionReturn() return 0; } +class SlowTask : public QRunnable +{ +public: + static QAtomicInt cancel; + void run() Q_DECL_OVERRIDE { + int iter = 60; + while (--iter && !cancel.load()) + QThread::currentThread()->msleep(25); + } +}; + +QAtomicInt SlowTask::cancel; + void tst_QtConcurrentRun::exceptions() { QThreadPool pool; @@ -480,6 +493,30 @@ void tst_QtConcurrentRun::exceptions() } if (!caught) QFAIL("did not get exception"); + + caught = false; + try { + QtConcurrent::run(&pool, throwFunctionReturn).result(); + } catch (QException &) { + caught = true; + } + QVERIFY2(caught, "did not get exception"); + + // Force the task to be run on this thread. + caught = false; + QThreadPool shortPool; + shortPool.setMaxThreadCount(1); + SlowTask *st = new SlowTask(); + try { + shortPool.start(st); + QtConcurrent::run(&shortPool, throwFunctionReturn).result(); + } catch (QException &) { + caught = true; + } + + SlowTask::cancel.store(true); + + QVERIFY2(caught, "did not get exception"); } #endif From 680ec54a76eaf63375f648819ac9f98c915e5c43 Mon Sep 17 00:00:00 2001 From: Raphael Kubo da Costa Date: Mon, 22 Aug 2016 19:55:10 +0200 Subject: [PATCH 04/24] QMutex: Make freelist() return a real global static Since Qt 5.6.0, some applications such as Kate (built with clang, libc++ and libcxxrt) on FreeBSD occasionally crash with the following error message on exit: QMutex::lock(): sem_wait failure: Invalid argument [or pthread_cond_wait in the 5.6 branch] Investigation by Gleb Popov, Thiago Macieira and Olivier Goffart has shown that this is caused by the fact that QDBusConnectionManager is a Q_GLOBAL_STATIC (so it will be destroyed with all the other Q_GLOBAL_STATICs in the reverse order of construction). In the Q_COMPILER_THREADSAFE_STATICS case, freelist() also returns a function-level static that is constructed on first use, so it may be destroyed earlier than the QDBusConnectionManager object, making it impossible to lock a contended mutex. We now make freelist() return a global static, so that it is always destroyed after QDBusConnectionManager and other function-static variables. Change-Id: I210fa7c18dbdf2345863da49141b9a85cffdef52 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/thread/qmutex.cpp | 27 ++------------------------- 1 file changed, 2 insertions(+), 25 deletions(-) diff --git a/src/corelib/thread/qmutex.cpp b/src/corelib/thread/qmutex.cpp index fa3bb080ae1..e9709e34c50 100644 --- a/src/corelib/thread/qmutex.cpp +++ b/src/corelib/thread/qmutex.cpp @@ -571,34 +571,11 @@ const int FreeListConstants::Sizes[FreeListConstants::BlockCount] = { typedef QFreeList FreeList; // We cannot use Q_GLOBAL_STATIC because it uses QMutex -#if defined(Q_COMPILER_THREADSAFE_STATICS) +static FreeList freeList_; FreeList *freelist() { - static FreeList list; - return &list; + return &freeList_; } -#else -static QBasicAtomicPointer freeListPtr; - -FreeList *freelist() -{ - FreeList *local = freeListPtr.loadAcquire(); - if (!local) { - local = new FreeList; - if (!freeListPtr.testAndSetRelease(0, local)) { - delete local; - local = freeListPtr.loadAcquire(); - } - } - return local; -} - -static void qFreeListDeleter() -{ - delete freeListPtr.load(); -} -Q_DESTRUCTOR_FUNCTION(qFreeListDeleter) -#endif } QMutexPrivate *QMutexPrivate::allocate() From f1808e96c5c45c95e6852481fe1ff71bda108811 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Tue, 23 Aug 2016 10:27:45 +0200 Subject: [PATCH 05/24] Fix crash for dereferencing zero Some targets do not support QFileSystemWatcher causing QFileSystemModel::iconProvider() to return zero. Change-Id: I3d2b7034b9fb805237c66a7dcea4457bfa41d46d Reviewed-by: Friedemann Kleint --- src/widgets/dialogs/qsidebar.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/widgets/dialogs/qsidebar.cpp b/src/widgets/dialogs/qsidebar.cpp index bb61135cbc6..3534588c560 100644 --- a/src/widgets/dialogs/qsidebar.cpp +++ b/src/widgets/dialogs/qsidebar.cpp @@ -192,7 +192,9 @@ void QUrlModel::setUrl(const QModelIndex &index, const QUrl &url, const QModelIn QIcon newIcon = qvariant_cast(dirIndex.data(Qt::DecorationRole)); if (!dirIndex.isValid()) { - newIcon = fileSystemModel->iconProvider()->icon(QFileIconProvider::Folder); + const QFileIconProvider *provider = fileSystemModel->iconProvider(); + if (provider) + newIcon = provider->icon(QFileIconProvider::Folder); newName = QFileInfo(url.toLocalFile()).fileName(); if (!invalidUrls.contains(url)) invalidUrls.append(url); From 4d07042c70c0d2f60ef35760a8211362de58a879 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Tue, 23 Aug 2016 10:37:54 +0200 Subject: [PATCH 06/24] winrt: Fix crash when clearing mimedata Some autotests clear the clipboard by invoking setMimeData() with a null QMimeData argument. Change-Id: I4a9d3dfd41b2c52964e272fc1362162f47fd8cda Reviewed-by: Oliver Wolff --- src/plugins/platforms/winrt/qwinrtclipboard.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/winrt/qwinrtclipboard.cpp b/src/plugins/platforms/winrt/qwinrtclipboard.cpp index 4e71490902f..c3850182396 100644 --- a/src/plugins/platforms/winrt/qwinrtclipboard.cpp +++ b/src/plugins/platforms/winrt/qwinrtclipboard.cpp @@ -143,7 +143,7 @@ void QWinRTClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode) return; #ifndef Q_OS_WINPHONE - const QString text = data->text(); + const QString text = data ? data->text() : QString(); HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([this, text]() { HRESULT hr; ComPtr package; From 1e1eddb2deb216bed6ccc9ebc8e4900bf7a4b502 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Tue, 23 Aug 2016 10:46:09 +0200 Subject: [PATCH 07/24] Fix crash in dumpConfiguration Some qpa backends do not provide a QPlatformNativeInterface. Hence, check whether return value is valid. Change-Id: Iab46bc59a151aa244fcfebf58edb37496369db89 Reviewed-by: Oliver Wolff --- tests/auto/gui/qopenglconfig/tst_qopenglconfig.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/tests/auto/gui/qopenglconfig/tst_qopenglconfig.cpp b/tests/auto/gui/qopenglconfig/tst_qopenglconfig.cpp index 1cb7972cc6e..e3e53975221 100644 --- a/tests/auto/gui/qopenglconfig/tst_qopenglconfig.cpp +++ b/tests/auto/gui/qopenglconfig/tst_qopenglconfig.cpp @@ -157,11 +157,13 @@ static void dumpConfiguration(QTextStream &str) } // On Windows, this will provide addition GPU info similar to the output of dxdiag. - const QVariant gpuInfoV = QGuiApplication::platformNativeInterface()->property("gpu"); - if (gpuInfoV.type() == QVariant::Map) { - const QString description = gpuInfoV.toMap().value(QStringLiteral("printable")).toString(); - if (!description.isEmpty()) - str << "\nGPU:\n" << description << "\n\n"; + if (QGuiApplication::platformNativeInterface()) { + const QVariant gpuInfoV = QGuiApplication::platformNativeInterface()->property("gpu"); + if (gpuInfoV.type() == QVariant::Map) { + const QString description = gpuInfoV.toMap().value(QStringLiteral("printable")).toString(); + if (!description.isEmpty()) + str << "\nGPU:\n" << description << "\n\n"; + } } } From a9474d1260a8c8cc9eae14f2984098919d9684e5 Mon Sep 17 00:00:00 2001 From: Raphael Kubo da Costa Date: Tue, 23 Aug 2016 20:25:14 +0200 Subject: [PATCH 08/24] configure: Correctly detect clang's version on FreeBSD "clang -v" on FreeBSD reports something like "FreeBSD clang version x.y.z [...]" instead of just "clang version x.y.z [...]", which fails to match the sed pattern in the configure script, resulting in qconfig.pri having no clang version defined. Augment the pattern so that both version strings match. Change-Id: I5f38f8480f4b1156ca7147e32c1157a009557035 Reviewed-by: Thiago Macieira --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index f4c7813fd04..e590da9514e 100755 --- a/configure +++ b/configure @@ -6697,7 +6697,7 @@ case "$QMAKE_CONF_COMPILER" in # Clang COMPILER_VERSION=`${QMAKE_CONF_COMPILER} -v 2>&1 | sed -n -E ' /^Apple (clang|LLVM) version /{s///; s/^([0-9]*)\.([0-9]*).*$/QT_APPLE_CLANG_MAJOR_VERSION=\1; QT_APPLE_CLANG_MINOR_VERSION=\2/;p;q;} -/^clang version /{s///; s/^([0-9]*)\.([0-9]*).*$/QT_CLANG_MAJOR_VERSION=\1; QT_CLANG_MINOR_VERSION=\2/;p;q;}'` +/^(FreeBSD )?clang version /{s///; s/^([0-9]*)\.([0-9]*).*$/QT_CLANG_MAJOR_VERSION=\1; QT_CLANG_MINOR_VERSION=\2/;p;q;}'` eval "$COMPILER_VERSION" ;; *icpc) From 16a421aa834dde5b8dd276444718053b8842f894 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 24 Aug 2016 14:01:05 +0200 Subject: [PATCH 09/24] Xcode: Don't enable document versioning debugging It results in passing an option on the command line that e.g. the QCommandLineParser doesn't understand. Change-Id: Ied08c930fab479b6432f025dfe861bdf22c513e6 Reviewed-by: Richard Moe Gustavsen --- mkspecs/macx-xcode/default.xcscheme | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mkspecs/macx-xcode/default.xcscheme b/mkspecs/macx-xcode/default.xcscheme index ab2f6a8ab77..6beb0d82804 100644 --- a/mkspecs/macx-xcode/default.xcscheme +++ b/mkspecs/macx-xcode/default.xcscheme @@ -62,7 +62,7 @@ useCustomWorkingDirectory = "NO" buildConfiguration = "Debug" ignoresPersistentStateOnLaunch = "NO" - debugDocumentVersioning = "YES" + debugDocumentVersioning = "NO" allowLocationSimulation = "YES"> + debugDocumentVersioning = "NO"> Date: Wed, 24 Aug 2016 12:14:59 +0200 Subject: [PATCH 10/24] multiwindow: Base fps on number of frames swapped, not timing of last frame Change-Id: I582e4f35b2702ac3792c5641fa10f74a79351bed Reviewed-by: Simon Hausmann --- .../manual/qopenglwindow/multiwindow/main.cpp | 30 +++++++++++++------ 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/tests/manual/qopenglwindow/multiwindow/main.cpp b/tests/manual/qopenglwindow/multiwindow/main.cpp index 47616ded0f8..7c4b143cf99 100644 --- a/tests/manual/qopenglwindow/multiwindow/main.cpp +++ b/tests/manual/qopenglwindow/multiwindow/main.cpp @@ -69,12 +69,15 @@ class Window : public QOpenGLWindow { + Q_OBJECT public: Window(int n) : idx(n) { r = g = b = fps = 0; y = 0; resize(200, 200); - t2.start(); + + connect(this, SIGNAL(frameSwapped()), SLOT(frameSwapped())); + fpsTimer.start(); } void paintGL() { @@ -106,20 +109,27 @@ public: if (y > height() - 20) y = 20; - if (t2.elapsed() > 1000) { - fps = 1000.0 / t.elapsed(); - t2.restart(); - } - t.restart(); - update(); } +public slots: + void frameSwapped() { + ++framesSwapped; + if (fpsTimer.elapsed() > 1000) { + fps = qRound(framesSwapped * (1000.0 / fpsTimer.elapsed())); + framesSwapped = 0; + fpsTimer.restart(); + } + } + private: int idx; - GLfloat r, g, b, fps; + GLfloat r, g, b; int y; - QElapsedTimer t, t2; + + int framesSwapped; + QElapsedTimer fpsTimer; + int fps; }; int main(int argc, char **argv) @@ -167,3 +177,5 @@ int main(int argc, char **argv) qDeleteAll(extraWindows); return r; } + +#include "main.moc" From 86ebd92addfcb6168875351f5af2fab89be3730f Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 25 Jul 2016 14:02:43 +0200 Subject: [PATCH 11/24] iOS, mkspec: update UUID parsing to support Xcode 8 beta MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "simctl list devices" has changed output format in Xcode 8 beta to include additional information placed inside parentheses for each device. And this confuses the scripts we use to parse and find UUIDs. Instead of making the inline scripts even longer and more complex, this patch will factor most of it out to a separate perl script that reads out device information on json format and parses the UUID. Change-Id: I3cd4dc276ecda030fda1932073c8bf1e0bc85deb Reviewed-by: Oswald Buddenhagen Reviewed-by: Tor Arne Vestbø --- mkspecs/macx-ios-clang/ios_destinations.sh | 3 +- mkspecs/macx-ios-clang/ios_devices.pl | 50 ++++++++++++++++++++++ mkspecs/macx-ios-clang/xcodebuild.mk | 5 ++- 3 files changed, 55 insertions(+), 3 deletions(-) create mode 100755 mkspecs/macx-ios-clang/ios_devices.pl diff --git a/mkspecs/macx-ios-clang/ios_destinations.sh b/mkspecs/macx-ios-clang/ios_destinations.sh index ce6b238a659..b85f59ca307 100755 --- a/mkspecs/macx-ios-clang/ios_destinations.sh +++ b/mkspecs/macx-ios-clang/ios_destinations.sh @@ -33,7 +33,8 @@ ## ############################################################################# -booted_simulator=$(xcrun simctl list devices | grep -E "iPhone|iPad" | grep -v unavailable | grep Booted | perl -lne 'print $1 if /\((.*?)\)/') +DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +booted_simulator=$($DIR/ios_devices.pl "iPhone|iPad" "Booted" "NOT unavailable" | tail -n 1) echo "IPHONESIMULATOR_DEVICES = $booted_simulator" xcodebuild test -scheme $1 -destination 'id=0' -destination-timeout 1 2>&1| sed -n 's/{ \(platform:.*\) }/\1/p' | while read destination; do diff --git a/mkspecs/macx-ios-clang/ios_devices.pl b/mkspecs/macx-ios-clang/ios_devices.pl new file mode 100755 index 00000000000..eb45d1dab9b --- /dev/null +++ b/mkspecs/macx-ios-clang/ios_devices.pl @@ -0,0 +1,50 @@ +#!/usr/bin/perl + +############################################################################# +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is the build configuration utility of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:LGPL21$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see http://www.qt.io/terms-conditions. For further +## information use the contact form at http://www.qt.io/contact-us. +## +## GNU Lesser General Public License Usage +## Alternatively, this file may be used under the terms of the GNU Lesser +## General Public License version 2.1 or version 3 as published by the Free +## Software Foundation and appearing in the file LICENSE.LGPLv21 and +## LICENSE.LGPLv3 included in the packaging of this file. Please review the +## following information to ensure the GNU Lesser General Public License +## requirements will be met: https://www.gnu.org/licenses/lgpl.html and +## http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +## +## As a special exception, The Qt Company gives you certain additional +## rights. These rights are described in The Qt Company LGPL Exception +## version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +## +## $QT_END_LICENSE$ +## +############################################################################# + +$output = `xcrun simctl list devices --json 2>&1`; +$output =~ s/\n//g; + +BLOCK: +foreach $block ($output =~ /{.*?}/g) { + foreach $filter (@ARGV) { + if ($filter =~ /^NOT\s(.*)/) { + $block =~ /$1/ && next BLOCK; + } else { + $block =~ /$filter/ || next BLOCK; + } + } + $block =~ /udid[:|\s|\"]+(.*)\"/; + print "$1\n"; +} diff --git a/mkspecs/macx-ios-clang/xcodebuild.mk b/mkspecs/macx-ios-clang/xcodebuild.mk index 1bd18430dfc..bf6b7913687 100644 --- a/mkspecs/macx-ios-clang/xcodebuild.mk +++ b/mkspecs/macx-ios-clang/xcodebuild.mk @@ -56,11 +56,12 @@ iphonesimulator-install: ACTION = build release-%: CONFIGURATION = Release debug-%: CONFIGURATION = Debug +SPECDIR := $(dir $(lastword $(MAKEFILE_LIST))) + # Test and build (device) destinations ifneq ($(filter check%,$(MAKECMDGOALS)),) ifeq ($(DEVICES),) $(info Enumerating test destinations (you may override this by setting DEVICES explicitly), please wait...) - SPECDIR := $(dir $(lastword $(MAKEFILE_LIST))) DESTINATIONS_INCLUDE = /tmp/ios_destinations.mk $(shell $(SPECDIR)/ios_destinations.sh $(TARGET) > $(DESTINATIONS_INCLUDE)) include $(DESTINATIONS_INCLUDE) @@ -71,7 +72,7 @@ endif %-iphoneos: DEVICES = $(IPHONEOS_DEVICES) IPHONEOS_GENERIC_DESTINATION := "generic/platform=iOS" -IPHONESIMULATOR_GENERIC_DESTINATION := "id=$(shell xcrun simctl list devices | grep -E 'iPhone|iPad' | grep -v unavailable | perl -lne 'print $$1 if /\((.*?)\)/' | tail -n 1)" +IPHONESIMULATOR_GENERIC_DESTINATION := "id=$(shell $(SPECDIR)/ios_devices.pl "iPhone|iPad" "NOT unavailable" | tail -n 1)" DESTINATION = $(if $(DESTINATION_ID),"id=$(DESTINATION_ID)",$(value $(call toupper,$(call basesdk,$(SDK)))_GENERIC_DESTINATION)) From 2c5eb3e668ee50fce85c22cf8b64b7d1aa7a936e Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 22 Aug 2016 12:46:16 +0200 Subject: [PATCH 12/24] fix conditions relating to host_build in non-cross builds when it comes to compiler flags (be it warnings or include paths), it doesn't matter whether we building/using bootstrap libraries, but whether we are actually cross-building. amends c55bdc271f and d8be8110a. Change-Id: Idf988107e9cccc486672c0ee70dc9bdf8eab9d8c Reviewed-by: Lars Knoll --- mkspecs/features/qt_build_extra.prf | 2 +- mkspecs/features/qt_common.prf | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mkspecs/features/qt_build_extra.prf b/mkspecs/features/qt_build_extra.prf index 378f5bbd7c4..abdd7bc2b26 100644 --- a/mkspecs/features/qt_build_extra.prf +++ b/mkspecs/features/qt_build_extra.prf @@ -13,7 +13,7 @@ equals(TEMPLATE, subdirs): return() # It's likely that these extra flags will be wrong for host builds, # and the bootstrapped tools usually don't need them anyway. -host_build:force_bootstrap: return() +host_build:cross_compile: return() # The headersclean check needs defines and includes even for # header-only modules. diff --git a/mkspecs/features/qt_common.prf b/mkspecs/features/qt_common.prf index de9ba9dde92..171b96f4152 100644 --- a/mkspecs/features/qt_common.prf +++ b/mkspecs/features/qt_common.prf @@ -44,9 +44,9 @@ contains(TEMPLATE, .*lib) { QMAKE_PRL_INSTALL_REPLACE += lib_replace } -# The remainder of this file must not apply to bootstrapped tools, +# The remainder of this file must not apply to host tools/libraries, # as the host compiler's version and capabilities are not checked. -host_build:force_bootstrap: return() +host_build:cross_compile: return() warnings_are_errors:warning_clean { # If the module declares that it has does its clean-up of warnings, enable -Werror. From 35b871b2b67815a320e48c6beef45ce01326f097 Mon Sep 17 00:00:00 2001 From: David Faure Date: Tue, 23 Aug 2016 22:34:21 +0200 Subject: [PATCH 13/24] QStyleSheetStyle: don't call pixelMetric when not needed fixupBorder does nothing when bd is null, i.e. hasBorder() returns false. Change-Id: Ic88e3a793f32bd4ad25830ddad9dbd8100348279 Reviewed-by: Friedemann Kleint Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/widgets/styles/qstylesheetstyle.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp index cb3c2a410b6..568a4755e4e 100644 --- a/src/widgets/styles/qstylesheetstyle.cpp +++ b/src/widgets/styles/qstylesheetstyle.cpp @@ -996,15 +996,17 @@ QRenderRule::QRenderRule(const QVector &declarations, const QObject } } - if (const QWidget *widget = qobject_cast(object)) { - QStyleSheetStyle *style = const_cast(globalStyleSheetStyle); - if (!style) - style = qobject_cast(widget->style()); - if (style) - fixupBorder(style->nativeFrameWidth(widget)); + if (hasBorder()) { + if (const QWidget *widget = qobject_cast(object)) { + QStyleSheetStyle *style = const_cast(globalStyleSheetStyle); + if (!style) + style = qobject_cast(widget->style()); + if (style) + fixupBorder(style->nativeFrameWidth(widget)); + } + if (border()->hasBorderImage()) + defaultBackground = QBrush(); } - if (hasBorder() && border()->hasBorderImage()) - defaultBackground = QBrush(); } QRect QRenderRule::borderRect(const QRect& r) const From 3e453abc7d27066d444545ddbf9b4d7576dc7efb Mon Sep 17 00:00:00 2001 From: David Faure Date: Tue, 16 Aug 2016 13:40:09 +0200 Subject: [PATCH 14/24] QMimeType: use default locale rather than system locale This makes it possible for the application to control which language is used by QMimeType::comment() [ChangeLog][QtCore][QMimeType] QMimeType::comment() now uses the default locale rather than system locale, so that applications can control which language is being used. Task-number: QTBUG-50776 Change-Id: I82623b7c488035a4164fadaf37ebcc79a9fd6173 Reviewed-by: Thiago Macieira --- src/corelib/mimetypes/qmimeprovider.cpp | 2 +- src/corelib/mimetypes/qmimetype.cpp | 6 +++--- .../qmimedatabase/tst_qmimedatabase.cpp | 16 ++++++++++++++++ .../mimetypes/qmimedatabase/tst_qmimedatabase.h | 1 + 4 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/corelib/mimetypes/qmimeprovider.cpp b/src/corelib/mimetypes/qmimeprovider.cpp index 0c64db4d483..fbd14e2d5d4 100644 --- a/src/corelib/mimetypes/qmimeprovider.cpp +++ b/src/corelib/mimetypes/qmimeprovider.cpp @@ -576,7 +576,7 @@ void QMimeBinaryProvider::loadMimeTypePrivate(QMimeTypePrivate &data) QString comment; QString mainPattern; - const QString preferredLanguage = QLocale::system().name(); + const QString preferredLanguage = QLocale().name(); for (QStringList::const_reverse_iterator it = mimeFiles.crbegin(), end = mimeFiles.crend(); it != end; ++it) { // global first, then local. QFile qfile(*it); diff --git a/src/corelib/mimetypes/qmimetype.cpp b/src/corelib/mimetypes/qmimetype.cpp index e3b01bbb897..980e8c1e5ed 100644 --- a/src/corelib/mimetypes/qmimetype.cpp +++ b/src/corelib/mimetypes/qmimetype.cpp @@ -232,15 +232,15 @@ QString QMimeType::name() const /*! Returns the description of the MIME type to be displayed on user interfaces. - The system language (QLocale::system().name()) is used to select the appropriate translation. + The default language (QLocale().name()) is used to select the appropriate translation. */ QString QMimeType::comment() const { QMimeDatabasePrivate::instance()->provider()->loadMimeTypePrivate(*d); QStringList languageList; - languageList << QLocale::system().name(); - languageList << QLocale::system().uiLanguages(); + languageList << QLocale().name(); + languageList << QLocale().uiLanguages(); Q_FOREACH (const QString &language, languageList) { const QString lang = language == QLatin1String("C") ? QLatin1String("en_US") : language; const QString comm = d->localeComments.value(lang); diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp index bbc086b0482..9ca7e0001ae 100644 --- a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp +++ b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp @@ -132,6 +132,7 @@ tst_QMimeDatabase::tst_QMimeDatabase() void tst_QMimeDatabase::initTestCase() { + QLocale::setDefault(QLocale::c()); QVERIFY2(m_temporaryDir.isValid(), qPrintable(m_temporaryDir.errorString())); QStandardPaths::setTestModeEnabled(true); m_localMimeDir = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/mime"; @@ -450,6 +451,21 @@ void tst_QMimeDatabase::icons() QCOMPARE(pub.genericIconName(), QString::fromLatin1("x-office-document")); } +void tst_QMimeDatabase::comment() +{ + struct RestoreLocale + { + ~RestoreLocale() { QLocale::setDefault(QLocale::c()); } + } restoreLocale; + + QLocale::setDefault(QLocale("de")); + QMimeDatabase db; + QMimeType directory = db.mimeTypeForName(QStringLiteral("inode/directory")); + QCOMPARE(directory.comment(), QStringLiteral("Ordner")); + QLocale::setDefault(QLocale("fr")); + QCOMPARE(directory.comment(), QStringLiteral("dossier")); +} + // In here we do the tests that need some content in a temporary file. // This could also be added to shared-mime-info's testsuite... void tst_QMimeDatabase::mimeTypeForFileWithContent() diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.h b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.h index 4b703f15d79..4d9a360dd9b 100644 --- a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.h +++ b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.h @@ -60,6 +60,7 @@ private slots: void listAliases_data(); void listAliases(); void icons(); + void comment(); void mimeTypeForFileWithContent(); void mimeTypeForUrl(); void mimeTypeForData_data(); From acfc1cc362ab8e9a40b49194275a1335b0d54788 Mon Sep 17 00:00:00 2001 From: Jake Petroules Date: Tue, 23 Aug 2016 11:50:35 -0700 Subject: [PATCH 15/24] Fix warning: 'UITextInputTextFontKey' is deprecated first deprecated in iOS 8.0 - Use NSFontAttributeName instead Change-Id: I763efc498644ac234a712ebcefd07111b4444c98 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiostextresponder.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/ios/qiostextresponder.mm b/src/plugins/platforms/ios/qiostextresponder.mm index 0cf505930f6..4bef968de14 100644 --- a/src/plugins/platforms/ios/qiostextresponder.mm +++ b/src/plugins/platforms/ios/qiostextresponder.mm @@ -908,7 +908,7 @@ UIFont *uifont = [UIFont fontWithName:qfont.family().toNSString() size:qfont.pointSize()]; if (!uifont) return [NSDictionary dictionary]; - return [NSDictionary dictionaryWithObject:uifont forKey:UITextInputTextFontKey]; + return [NSDictionary dictionaryWithObject:uifont forKey:NSFontAttributeName]; } - (NSDictionary *)markedTextStyle From 59ee2584e203d2ea7f4051e97d9d86fae05861cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 19 Aug 2016 17:32:30 +0200 Subject: [PATCH 16/24] Make QWindow backed QOffscreenSurfaces easier to identify Change-Id: I2b4d9b752f4b356cb3b0019dcfd4aab2edc30e94 Reviewed-by: Laszlo Agocs --- src/gui/kernel/qoffscreensurface.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/kernel/qoffscreensurface.cpp b/src/gui/kernel/qoffscreensurface.cpp index 1a12ea4d320..18bfaea2a04 100644 --- a/src/gui/kernel/qoffscreensurface.cpp +++ b/src/gui/kernel/qoffscreensurface.cpp @@ -177,6 +177,7 @@ void QOffscreenSurface::create() if (QThread::currentThread() != qGuiApp->thread()) qWarning("Attempting to create QWindow-based QOffscreenSurface outside the gui thread. Expect failures."); d->offscreenWindow = new QWindow(d->screen); + d->offscreenWindow->setObjectName("QOffscreenSurface"); // Remove this window from the global list since we do not want it to be destroyed when closing the app. // The QOffscreenSurface has to be usable even after exiting the event loop. QGuiApplicationPrivate::window_list.removeOne(d->offscreenWindow); From d856d0e14663978f62c5e9c93396e25b0d466a97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 19 Aug 2016 18:34:15 +0200 Subject: [PATCH 17/24] Limit glyph caches per QFontEngine to four per context, not four in total The limitation of four glyph caches per font engine was to prevent memory spikes during rotation of text. But in an application with multiple top level OpenGL windows, each with their own context, we'd end up trashing the list of glyph caches during rendering, even if each window just drew the same static text. Having a shared context between the windows helped a bit, but had other performance issues due to the globally shared state, so the better approach is to limit the caches to four per context. This brings the multiwindow manual test from a grinding 4fps on macOS to a smooth 60fps for 20 concurrent windows. Task-number: QTBUG-52372 Change-Id: I26edd5f6edb5c7818e14b2203af062df19ae7127 Reviewed-by: Simon Hausmann --- src/gui/text/qfontengine.cpp | 61 +++++++++++++++++------------------- src/gui/text/qfontengine_p.h | 7 ++--- 2 files changed, 32 insertions(+), 36 deletions(-) diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index 5e8aac82b88..fa49b25073a 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -1046,46 +1046,45 @@ QByteArray QFontEngine::getSfntTable(uint tag) const return table; } -void QFontEngine::clearGlyphCache(const void *key) +void QFontEngine::clearGlyphCache(const void *context) { - for (QLinkedList::iterator it = m_glyphCaches.begin(), end = m_glyphCaches.end(); it != end; ) { - if (it->context == key) - it = m_glyphCaches.erase(it); - else - ++it; - } + m_glyphCaches.remove(context); } -void QFontEngine::setGlyphCache(const void *key, QFontEngineGlyphCache *data) +void QFontEngine::setGlyphCache(const void *context, QFontEngineGlyphCache *cache) { - Q_ASSERT(data); + Q_ASSERT(cache); + + GlyphCaches &caches = m_glyphCaches[context]; + for (GlyphCaches::const_iterator it = caches.constBegin(), end = caches.constEnd(); it != end; ++it) { + if (cache == it->cache.data()) + return; + } + + // Limit the glyph caches to 4 per context. This covers all 90 degree rotations, + // and limits memory use when there is continuous or random rotation + if (caches.size() == 4) + caches.removeLast(); GlyphCacheEntry entry; - entry.context = key; - entry.cache = data; - if (m_glyphCaches.contains(entry)) - return; - - // Limit the glyph caches to 4. This covers all 90 degree rotations and limits - // memory use when there is continuous or random rotation - if (m_glyphCaches.size() == 4) - m_glyphCaches.removeLast(); - - m_glyphCaches.push_front(entry); + entry.cache = cache; + caches.push_front(entry); } -QFontEngineGlyphCache *QFontEngine::glyphCache(const void *key, GlyphFormat format, const QTransform &transform) const +QFontEngineGlyphCache *QFontEngine::glyphCache(const void *context, GlyphFormat format, const QTransform &transform) const { - for (QLinkedList::const_iterator it = m_glyphCaches.constBegin(), end = m_glyphCaches.constEnd(); it != end; ++it) { - QFontEngineGlyphCache *c = it->cache.data(); - if (key == it->context - && format == c->glyphFormat() - && qtransform_equals_no_translate(c->m_transform, transform)) { - return c; - } + const QHash::const_iterator caches = m_glyphCaches.constFind(context); + if (caches == m_glyphCaches.cend()) + return Q_NULLPTR; + + for (GlyphCaches::const_iterator it = caches->begin(), end = caches->end(); it != end; ++it) { + QFontEngineGlyphCache *cache = it->cache.data(); + if (format == cache->glyphFormat() && qtransform_equals_no_translate(cache->m_transform, transform)) + return cache; } - return 0; + + return Q_NULLPTR; } static inline QFixed kerning(int left, int right, const QFontEngine::KernPair *pairs, int numPairs) @@ -1565,12 +1564,11 @@ QFixed QFontEngine::lastRightBearing(const QGlyphLayout &glyphs, bool round) QFontEngine::GlyphCacheEntry::GlyphCacheEntry() - : context(0) { } QFontEngine::GlyphCacheEntry::GlyphCacheEntry(const GlyphCacheEntry &o) - : context(o.context), cache(o.cache) + : cache(o.cache) { } @@ -1580,7 +1578,6 @@ QFontEngine::GlyphCacheEntry::~GlyphCacheEntry() QFontEngine::GlyphCacheEntry &QFontEngine::GlyphCacheEntry::operator=(const GlyphCacheEntry &o) { - context = o.context; cache = o.cache; return *this; } diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h index 7ddc5c0c328..39cf826ee27 100644 --- a/src/gui/text/qfontengine_p.h +++ b/src/gui/text/qfontengine_p.h @@ -316,12 +316,11 @@ private: GlyphCacheEntry &operator=(const GlyphCacheEntry &); - const void *context; QExplicitlySharedDataPointer cache; - bool operator==(const GlyphCacheEntry &other) const { return context == other.context && cache == other.cache; } + bool operator==(const GlyphCacheEntry &other) const { return cache == other.cache; } }; - - mutable QLinkedList m_glyphCaches; + typedef QLinkedList GlyphCaches; + mutable QHash m_glyphCaches; private: QVariant m_userData; From 10fe5091235fcff37e83d35e3c1b0040b60fe2a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 24 Aug 2016 12:59:40 +0200 Subject: [PATCH 18/24] multiwindow: Use QCommandLineParser instead of parsing manually Change-Id: I9d9e3ede6c8cce3aa1b42d0e98a0a5b19fefc73c Reviewed-by: Simon Hausmann --- .../manual/qopenglwindow/multiwindow/main.cpp | 59 +++++++++++-------- 1 file changed, 35 insertions(+), 24 deletions(-) diff --git a/tests/manual/qopenglwindow/multiwindow/main.cpp b/tests/manual/qopenglwindow/multiwindow/main.cpp index 7c4b143cf99..4533167dd79 100644 --- a/tests/manual/qopenglwindow/multiwindow/main.cpp +++ b/tests/manual/qopenglwindow/multiwindow/main.cpp @@ -37,26 +37,21 @@ #include #include #include +#include + +const char applicationDescription[] = "\n\ +This application opens multiple windows and continuously schedules updates for\n\ +them. Each of them is a separate QOpenGLWindow so there will be a separate\n\ +context and swapBuffers call for each.\n\ +\n\ +By default the swap interval is 1 so the effect of multiple blocking swapBuffers\n\ +on the main thread can be examined. (the result is likely to be different\n\ +between platforms, for example OS X is buffer queuing meaning that it can\n\ +block outside swap, resulting in perfect vsync for all three windows, while\n\ +other systems that block on swap will kill the frame rate due to blocking the\n\ +thread three times)\ +"; -// This application opens three windows and continuously schedules updates for -// them. Each of them is a separate QOpenGLWindow so there will be a separate -// context and swapBuffers call for each. -// -// By default the swap interval is 1 so the effect of three blocking swapBuffers -// on the main thread can be examined. (the result is likely to be different -// between platforms, for example OS X is buffer queuing meaning that it can -// block outside swap, resulting in perfect vsync for all three windows, while -// other systems that block on swap will kill the frame rate due to blocking the -// thread three times) -// -// Pass --novsync to set a swap interval of 0. This should give an unthrottled -// refresh on all platforms for all three windows. -// -// Passing --vsyncone sets swap interval to 1 for the first window and 0 to the -// others. -// -// Pass --extrawindows N to open N windows in addition to the default 3. -// // For reference, below is a table of some test results. // // swap interval 1 for all swap interval 1 for only one and 0 for others @@ -135,8 +130,26 @@ private: int main(int argc, char **argv) { QGuiApplication app(argc, argv); + + QCommandLineParser parser; + parser.setApplicationDescription(applicationDescription); + parser.addHelpOption(); + + QCommandLineOption noVsyncOption("novsync", "Disable Vsync by setting swap interval to 0. " + "This should give an unthrottled refresh on all platforms for all windows."); + parser.addOption(noVsyncOption); + + QCommandLineOption vsyncOneOption("vsyncone", "Enable Vsync only for first window, " + "by setting swap interval to 1 for the first window and 0 for the others."); + parser.addOption(vsyncOneOption); + + QCommandLineOption extraWindowsOption("extrawindows", "Open windows in addition to the default 3.", "N", "0"); + parser.addOption(extraWindowsOption); + + parser.process(app); + QSurfaceFormat fmt; - if (QGuiApplication::arguments().contains(QLatin1String("--novsync"))) { + if (parser.isSet(noVsyncOption)) { qDebug("swap interval 0 (no throttling)"); fmt.setSwapInterval(0); } else { @@ -145,7 +158,7 @@ int main(int argc, char **argv) QSurfaceFormat::setDefaultFormat(fmt); Window w1(0); - if (QGuiApplication::arguments().contains(QLatin1String("--vsyncone"))) { + if (parser.isSet(vsyncOneOption)) { qDebug("swap interval 1 for first window only"); QSurfaceFormat w1fmt = fmt; w1fmt.setSwapInterval(1); @@ -163,9 +176,7 @@ int main(int argc, char **argv) w3.show(); QList extraWindows; - int countIdx; - if ((countIdx = QGuiApplication::arguments().indexOf(QLatin1String("--extrawindows"))) >= 0) { - int extraWindowCount = QGuiApplication::arguments().at(countIdx + 1).toInt(); + if (int extraWindowCount = parser.value(extraWindowsOption).toInt()) { for (int i = 0; i < extraWindowCount; ++i) { Window *w = new Window(3 + i); extraWindows << w; From c1804bb5c198b3cc5364847ce2bb642161fa15f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 24 Aug 2016 13:53:10 +0200 Subject: [PATCH 19/24] multiwindow: Make it easier to test 1-N windows Changes the --extrawindows option to --numwindows with a default of 3, and layouts all windows in rows and columns so that they are all exposed at startup. Change-Id: I5e8d63a14b778bcddc2fee3bf7e78d6664532b5b Reviewed-by: Simon Hausmann --- .../manual/qopenglwindow/multiwindow/main.cpp | 58 ++++++++++--------- 1 file changed, 32 insertions(+), 26 deletions(-) diff --git a/tests/manual/qopenglwindow/multiwindow/main.cpp b/tests/manual/qopenglwindow/multiwindow/main.cpp index 4533167dd79..caa15078d55 100644 --- a/tests/manual/qopenglwindow/multiwindow/main.cpp +++ b/tests/manual/qopenglwindow/multiwindow/main.cpp @@ -38,6 +38,7 @@ #include #include #include +#include const char applicationDescription[] = "\n\ This application opens multiple windows and continuously schedules updates for\n\ @@ -143,8 +144,8 @@ int main(int argc, char **argv) "by setting swap interval to 1 for the first window and 0 for the others."); parser.addOption(vsyncOneOption); - QCommandLineOption extraWindowsOption("extrawindows", "Open windows in addition to the default 3.", "N", "0"); - parser.addOption(extraWindowsOption); + QCommandLineOption numWindowsOption("numwindows", "Open windows instead of the default 3.", "N", "3"); + parser.addOption(numWindowsOption); parser.process(app); @@ -157,35 +158,40 @@ int main(int argc, char **argv) } QSurfaceFormat::setDefaultFormat(fmt); - Window w1(0); - if (parser.isSet(vsyncOneOption)) { - qDebug("swap interval 1 for first window only"); - QSurfaceFormat w1fmt = fmt; - w1fmt.setSwapInterval(1); - w1.setFormat(w1fmt); - fmt.setSwapInterval(0); - QSurfaceFormat::setDefaultFormat(fmt); - } - Window w2(1); - Window w3(2); - w1.setGeometry(QRect(QPoint(10, 100), w1.size())); - w2.setGeometry(QRect(QPoint(300, 100), w2.size())); - w3.setGeometry(QRect(QPoint(600, 100), w3.size())); - w1.show(); - w2.show(); - w3.show(); + QRect availableGeometry = app.primaryScreen()->availableGeometry(); - QList extraWindows; - if (int extraWindowCount = parser.value(extraWindowsOption).toInt()) { - for (int i = 0; i < extraWindowCount; ++i) { - Window *w = new Window(3 + i); - extraWindows << w; - w->show(); + int numberOfWindows = qMax(parser.value(numWindowsOption).toInt(), 1); + QList windows; + for (int i = 0; i < numberOfWindows; ++i) { + Window *w = new Window(i + 1); + windows << w; + + if (i == 0 && parser.isSet(vsyncOneOption)) { + qDebug("swap interval 1 for first window only"); + QSurfaceFormat vsyncedSurfaceFormat = fmt; + vsyncedSurfaceFormat.setSwapInterval(1); + w->setFormat(vsyncedSurfaceFormat); + fmt.setSwapInterval(0); + QSurfaceFormat::setDefaultFormat(fmt); } + + static int windowWidth = w->width() + 20; + static int windowHeight = w->height() + 20; + + static int windowsPerRow = availableGeometry.width() / windowWidth; + + int col = i; + int row = col / windowsPerRow; + col -= row * windowsPerRow; + + QPoint position = availableGeometry.topLeft(); + position += QPoint(col * windowWidth, row * windowHeight); + w->setFramePosition(position); + w->show(); } int r = app.exec(); - qDeleteAll(extraWindows); + qDeleteAll(windows); return r; } From 6a35c6d491b0c0decbec0abc9b2b97c9c6ff5707 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sun, 21 Aug 2016 21:06:56 +0200 Subject: [PATCH 20/24] QKeySequence: replace an array end marker by static size calculation This improves code generation, since the compiler statically knows the number of loop iterations. But it also fixes a compile-error on Clang with a following change of the name field from char* to char[]. Change-Id: I7ef18adf3cb9b34cd1b7235cb35cf26b7e349d92 Reviewed-by: Friedemann Kleint Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/gui/kernel/qkeysequence.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp index 1934342f96e..45be89b51c0 100644 --- a/src/gui/kernel/qkeysequence.cpp +++ b/src/gui/kernel/qkeysequence.cpp @@ -687,8 +687,8 @@ static const struct { { Qt::Key_TouchpadOn, QT_TRANSLATE_NOOP("QShortcut", "Touchpad On") }, { Qt::Key_TouchpadOff, QT_TRANSLATE_NOOP("QShortcut", "Touchpad Off") }, - { 0, 0 } }; +static Q_CONSTEXPR int numKeyNames = sizeof keyname / sizeof *keyname; /*! \enum QKeySequence::StandardKey @@ -1172,7 +1172,7 @@ int QKeySequencePrivate::decodeString(const QString &str, QKeySequence::Sequence for (int tran = 0; tran < 2; ++tran) { if (!nativeText) ++tran; - for (int i = 0; keyname[i].name; ++i) { + for (int i = 0; i < numKeyNames; ++i) { QString keyName(tran == 0 ? QCoreApplication::translate("QShortcut", keyname[i].name) : QString::fromLatin1(keyname[i].name)); @@ -1311,7 +1311,7 @@ QString QKeySequencePrivate::keyName(int key, QKeySequence::SequenceFormat forma #if defined(Q_OS_MACX) NonSymbol: #endif - while (keyname[i].name) { + while (i < numKeyNames) { if (key == keyname[i].key) { p = nativeText ? QCoreApplication::translate("QShortcut", keyname[i].name) : QString::fromLatin1(keyname[i].name); @@ -1323,7 +1323,7 @@ NonSymbol: // fall back on the unicode representation of it... // Or else characters like Qt::Key_aring may not get displayed // (Really depends on you locale) - if (!keyname[i].name) { + if (i >= numKeyNames) { if (!QChar::requiresSurrogates(key)) { p = QChar(ushort(key)).toUpper(); } else { From 6a44c0ee75d0e6395aae9a2a6658d2b730ba38ba Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Fri, 19 Aug 2016 12:59:09 +0200 Subject: [PATCH 21/24] QKeySequence: remove 239 unneeded relocations Same change as in QColor (d38f86e50b01c6dd60f5a97355031e08d6a47d18). relocs: -239 text: -586B data: -3840B (optimized GCC 6.1 Linux AMD64 build). Change-Id: I180e9b65736481dd4e82dc68ef6c3f7541e205cf Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/gui/kernel/qkeysequence.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp index 45be89b51c0..ea71e34e4ba 100644 --- a/src/gui/kernel/qkeysequence.cpp +++ b/src/gui/kernel/qkeysequence.cpp @@ -405,7 +405,7 @@ void Q_GUI_EXPORT qt_set_sequence_auto_mnemonic(bool b) { qt_sequence_no_mnemoni static const struct { int key; - const char* name; + const char name[25]; } keyname[] = { //: This and all following "incomprehensible" strings in QShortcut context //: are key names. Please use the localized names appearing on actual From 2aea77dbcb8a3da40cf040bef63977514708056b Mon Sep 17 00:00:00 2001 From: Lorn Potter Date: Mon, 18 Jul 2016 19:19:25 +1000 Subject: [PATCH 22/24] Fix UI freeze when using network-manager bearer plugin This reduces the amount of dbus signals generated when many wifi AP's are around Task-number: QTBUG-54814 Change-Id: I4bdd5f0bfe173d6db63f3d975a98583c6c0fc5db Reviewed-by: Richard J. Moore --- .../networkmanager/qnetworkmanagerengine.cpp | 194 +----------------- .../networkmanager/qnetworkmanagerengine.h | 7 - .../networkmanager/qnetworkmanagerservice.cpp | 142 +++++-------- .../networkmanager/qnetworkmanagerservice.h | 11 - 4 files changed, 60 insertions(+), 294 deletions(-) diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp index 13b64a556c7..1b1034817e4 100644 --- a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp +++ b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp @@ -123,6 +123,9 @@ void QNetworkManagerEngine::setupConfigurations() // Get active connections. foreach (const QDBusObjectPath &acPath, managerInterface->activeConnections()) { + if (activeConnectionsList.contains(acPath.path())) + continue; + QNetworkManagerConnectionActive *activeConnection = new QNetworkManagerConnectionActive(acPath.path(),this); activeConnectionsList.insert(acPath.path(), activeConnection); @@ -135,14 +138,6 @@ void QNetworkManagerEngine::setupConfigurations() connectionInterfaces.insert(activeConnection->connection().path(),device.networkInterface()); } } - - // Get current list of access points. - foreach (const QDBusObjectPath &devicePath, managerInterface->getDevices()) { - locker.unlock(); - deviceAdded(devicePath); //add all accesspoints - locker.relock(); - } - // Get connections. foreach (const QDBusObjectPath &settingsPath, systemSettings->listConnections()) { locker.unlock(); @@ -251,11 +246,6 @@ void QNetworkManagerEngine::requestUpdate() QMetaObject::invokeMethod(this, "updateCompleted", Qt::QueuedConnection); } -void QNetworkManagerEngine::scanFinished() -{ - QMetaObject::invokeMethod(this, "updateCompleted", Qt::QueuedConnection); -} - void QNetworkManagerEngine::interfacePropertiesChanged(const QMap &properties) { QMutexLocker locker(&mutex); @@ -397,57 +387,6 @@ void QNetworkManagerEngine::deviceConnectionsChanged(const QStringList &connecti } } -void QNetworkManagerEngine::deviceAdded(const QDBusObjectPath &path) -{ - QNetworkManagerInterfaceDevice *iDevice; - iDevice = new QNetworkManagerInterfaceDevice(path.path(),this); - connect(iDevice,SIGNAL(connectionsChanged(QStringList)), - this,SLOT(deviceConnectionsChanged(QStringList))); - - interfaceDevices.insert(path.path(),iDevice); - if (iDevice->deviceType() == DEVICE_TYPE_WIFI) { - QNetworkManagerInterfaceDeviceWireless *wirelessDevice = - new QNetworkManagerInterfaceDeviceWireless(iDevice->path(),this); - - connect(wirelessDevice, SIGNAL(accessPointAdded(QString)), - this, SLOT(newAccessPoint(QString))); - connect(wirelessDevice, SIGNAL(accessPointRemoved(QString)), - this, SLOT(removeAccessPoint(QString))); - connect(wirelessDevice,SIGNAL(scanDone()),this,SLOT(scanFinished())); - wirelessDevice->setConnections(); - - wirelessDevices.insert(path.path(), wirelessDevice); - } - - if (iDevice->deviceType() == DEVICE_TYPE_ETHERNET) { - QNetworkManagerInterfaceDeviceWired *wiredDevice = - new QNetworkManagerInterfaceDeviceWired(iDevice->path(),this); - connect(wiredDevice,SIGNAL(carrierChanged(bool)),this,SLOT(wiredCarrierChanged(bool))); - wiredDevices.insert(iDevice->path(), wiredDevice); - } -} - -void QNetworkManagerEngine::deviceRemoved(const QDBusObjectPath &path) -{ - QMutexLocker locker(&mutex); - - if (interfaceDevices.contains(path.path())) { - locker.unlock(); - delete interfaceDevices.take(path.path()); - locker.relock(); - } - if (wirelessDevices.contains(path.path())) { - locker.unlock(); - delete wirelessDevices.take(path.path()); - locker.relock(); - } - if (wiredDevices.contains(path.path())) { - locker.unlock(); - delete wiredDevices.take(path.path()); - locker.relock(); - } -} - void QNetworkManagerEngine::wiredCarrierChanged(bool carrier) { QNetworkManagerInterfaceDeviceWired *deviceWired = qobject_cast(sender()); @@ -538,7 +477,7 @@ void QNetworkManagerEngine::newConnection(const QDBusObjectPath &path, if (i.value()->deviceType() == deviceType) { QNetworkManagerInterfaceDeviceWired *wiredDevice = wiredDevices.value(i.value()->path()); - if (wiredDevice->carrier()) { + if (wiredDevice && wiredDevice->carrier()) { cpPriv->state |= QNetworkConfiguration::Discovered; } } @@ -596,15 +535,10 @@ void QNetworkManagerEngine::removeConnection(const QString &path) emit configurationRemoved(ptr); locker.relock(); } + // add base AP back into configurations - QMapIterator i(configuredAccessPoints); - while (i.hasNext()) { - i.next(); - if (i.value() == path) { - configuredAccessPoints.remove(i.key()); - newAccessPoint(i.key()); - } - } + + // removed along with all AP props code... } void QNetworkManagerEngine::updateConnection() @@ -678,114 +612,6 @@ void QNetworkManagerEngine::activationFinished(QDBusPendingCallWatcher *watcher) } } -void QNetworkManagerEngine::newAccessPoint(const QString &path) -{ - QMutexLocker locker(&mutex); - QNetworkManagerInterfaceAccessPoint *accessPoint = - new QNetworkManagerInterfaceAccessPoint(path,this); - - bool okToAdd = true; - for (int i = 0; i < accessPoints.count(); ++i) { - if (accessPoints.at(i)->path() == path) { - okToAdd = false; - } - } - if (okToAdd) { - accessPoints.append(accessPoint); - } - // Check if configuration exists for connection. - if (!accessPoint->ssid().isEmpty()) { - - for (int i = 0; i < connections.count(); ++i) { - QNetworkManagerSettingsConnection *connection = connections.at(i); - const QString settingsPath = connection->path(); - - if (accessPoint->ssid() == connection->getSsid()) { - if (!configuredAccessPoints.contains(path)) { - configuredAccessPoints.insert(path,settingsPath); - } - - QNetworkConfigurationPrivatePointer ptr = - accessPointConfigurations.value(settingsPath); - ptr->mutex.lock(); - QNetworkConfiguration::StateFlags flag = QNetworkConfiguration::Defined; - ptr->state = (flag | QNetworkConfiguration::Discovered); - - if (isConnectionActive(settingsPath)) - ptr->state = (flag | QNetworkConfiguration::Active); - ptr->mutex.unlock(); - - locker.unlock(); - emit configurationChanged(ptr); - return; - } - } - } - - // New access point. - QNetworkConfigurationPrivatePointer ptr(new QNetworkConfigurationPrivate); - - ptr->name = accessPoint->ssid(); - ptr->isValid = true; - ptr->id = path; - ptr->type = QNetworkConfiguration::InternetAccessPoint; - ptr->purpose = QNetworkConfiguration::PublicPurpose; - ptr->state = QNetworkConfiguration::Undefined; - ptr->bearerType = QNetworkConfiguration::BearerWLAN; - - accessPointConfigurations.insert(ptr->id, ptr); - - locker.unlock(); - emit configurationAdded(ptr); -} - -void QNetworkManagerEngine::removeAccessPoint(const QString &path) -{ - QMutexLocker locker(&mutex); - for (int i = 0; i < accessPoints.count(); ++i) { - QNetworkManagerInterfaceAccessPoint *accessPoint = accessPoints.at(i); - if (accessPoint->path() == path) { - accessPoints.removeOne(accessPoint); - - if (configuredAccessPoints.contains(accessPoint->path())) { - // find connection and change state to Defined - configuredAccessPoints.remove(accessPoint->path()); - - for (int i = 0; i < connections.count(); ++i) { - QNetworkManagerSettingsConnection *connection = connections.at(i); - - if (accessPoint->ssid() == connection->getSsid()) {//might not have bssid yet - const QString settingsPath = connection->path(); - const QString connectionId = settingsPath; - - QNetworkConfigurationPrivatePointer ptr = - accessPointConfigurations.value(connectionId); - ptr->mutex.lock(); - ptr->state = QNetworkConfiguration::Defined; - ptr->mutex.unlock(); - - locker.unlock(); - emit configurationChanged(ptr); - locker.relock(); - break; - } - } - } else { - QNetworkConfigurationPrivatePointer ptr = - accessPointConfigurations.take(path); - - if (ptr) { - locker.unlock(); - emit configurationRemoved(ptr); - locker.relock(); - } - } - delete accessPoint; - break; - } - } -} - QNetworkConfigurationPrivate *QNetworkManagerEngine::parseConnection(const QString &settingsPath, const QNmSettingsMap &map) { @@ -808,7 +634,7 @@ QNetworkConfigurationPrivate *QNetworkManagerEngine::parseConnection(const QStri QNetworkManagerInterfaceDevice device(devicePath.path(),this); if (device.deviceType() == DEVICE_TYPE_ETHERNET) { QNetworkManagerInterfaceDeviceWired *wiredDevice = wiredDevices.value(device.path()); - if (wiredDevice->carrier()) { + if (wiredDevice && wiredDevice->carrier()) { cpPriv->state |= QNetworkConfiguration::Discovered; break; } @@ -1078,10 +904,6 @@ void QNetworkManagerEngine::nmRegistered(const QString &) managerInterface = new QNetworkManagerInterface(this); systemSettings = new QNetworkManagerSettings(NM_DBUS_SERVICE, this); - connect(managerInterface, SIGNAL(deviceAdded(QDBusObjectPath)), - this, SLOT(deviceAdded(QDBusObjectPath))); - connect(managerInterface, SIGNAL(deviceRemoved(QDBusObjectPath)), - this, SLOT(deviceRemoved(QDBusObjectPath))); connect(managerInterface, SIGNAL(activationFinished(QDBusPendingCallWatcher*)), this, SLOT(activationFinished(QDBusPendingCallWatcher*))); connect(managerInterface, SIGNAL(propertiesChanged(QMap)), diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.h b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.h index 1f578890dcb..b859318a5b1 100644 --- a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.h +++ b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.h @@ -93,19 +93,12 @@ private Q_SLOTS: void interfacePropertiesChanged(const QMap &properties); void activeConnectionPropertiesChanged(const QMap &properties); - void deviceAdded(const QDBusObjectPath &path); - void deviceRemoved(const QDBusObjectPath &path); - void newConnection(const QDBusObjectPath &path, QNetworkManagerSettings *settings = 0); void removeConnection(const QString &path); void updateConnection(); void activationFinished(QDBusPendingCallWatcher *watcher); void deviceConnectionsChanged(const QStringList &activeConnectionsList); - void newAccessPoint(const QString &path); - void removeAccessPoint(const QString &path); - void scanFinished(); - void wiredCarrierChanged(bool); void nmRegistered(const QString &serviceName = QString()); diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp index d550887ba6d..7506b768f20 100644 --- a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp +++ b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp @@ -95,6 +95,21 @@ QNetworkManagerInterface::QNetworkManagerInterface(QObject *parent) QNetworkManagerInterface::~QNetworkManagerInterface() { + QDBusConnection::systemBus().disconnect(QLatin1String(NM_DBUS_SERVICE), + QLatin1String(NM_DBUS_PATH), + QLatin1String(NM_DBUS_INTERFACE), + QLatin1String("PropertiesChanged"), + this,SLOT(propertiesSwap(QMap))); + QDBusConnection::systemBus().disconnect(QLatin1String(NM_DBUS_SERVICE), + QLatin1String(NM_DBUS_PATH), + QLatin1String(NM_DBUS_INTERFACE), + QLatin1String("DeviceAdded"), + this,SIGNAL(deviceAdded(QDBusObjectPath))); + QDBusConnection::systemBus().disconnect(QLatin1String(NM_DBUS_SERVICE), + QLatin1String(NM_DBUS_PATH), + QLatin1String(NM_DBUS_INTERFACE), + QLatin1String("DeviceRemoved"), + this,SIGNAL(deviceRemoved(QDBusObjectPath))); } bool QNetworkManagerInterface::setConnections() @@ -235,28 +250,6 @@ QNetworkManagerInterfaceAccessPoint::QNetworkManagerInterfaceAccessPoint(const Q NM_DBUS_INTERFACE_ACCESS_POINT, QDBusConnection::systemBus(),parent) { - if (!isValid()) { - return; - } - PropertiesDBusInterface *accessPointPropertiesInterface = new PropertiesDBusInterface(QLatin1String(NM_DBUS_SERVICE), - dbusPathName, - DBUS_PROPERTIES_INTERFACE, - QDBusConnection::systemBus()); - - QList argumentList; - argumentList << QLatin1String(NM_DBUS_INTERFACE_ACCESS_POINT); - QDBusPendingReply propsReply - = accessPointPropertiesInterface->callWithArgumentList(QDBus::Block,QLatin1String("GetAll"), - argumentList); - if (!propsReply.isError()) { - propertyMap = propsReply.value(); - } - - QDBusConnection::systemBus().connect(QLatin1String(NM_DBUS_SERVICE), - dbusPathName, - QLatin1String(NM_DBUS_INTERFACE_ACCESS_POINT), - QLatin1String("PropertiesChanged"), - this,SLOT(propertiesSwap(QMap))); } QNetworkManagerInterfaceAccessPoint::~QNetworkManagerInterfaceAccessPoint() @@ -369,6 +362,11 @@ QNetworkManagerInterfaceDevice::QNetworkManagerInterfaceDevice(const QString &de QNetworkManagerInterfaceDevice::~QNetworkManagerInterfaceDevice() { + QDBusConnection::systemBus().disconnect(QLatin1String(NM_DBUS_SERVICE), + path(), + QLatin1String(NM_DBUS_INTERFACE_DEVICE), + QLatin1String("PropertiesChanged"), + this,SLOT(propertiesSwap(QMap))); } QString QNetworkManagerInterfaceDevice::udi() const @@ -468,6 +466,11 @@ QNetworkManagerInterfaceDeviceWired::QNetworkManagerInterfaceDeviceWired(const Q QNetworkManagerInterfaceDeviceWired::~QNetworkManagerInterfaceDeviceWired() { + QDBusConnection::systemBus().disconnect(QLatin1String(NM_DBUS_SERVICE), + path(), + QLatin1String(NM_DBUS_INTERFACE_DEVICE_WIRED), + QLatin1String("PropertiesChanged"), + this,SLOT(propertiesSwap(QMap))); } QString QNetworkManagerInterfaceDeviceWired::hwAddress() const @@ -557,77 +560,20 @@ QNetworkManagerInterfaceDeviceWireless::QNetworkManagerInterfaceDeviceWireless(c QLatin1String(NM_DBUS_INTERFACE_DEVICE_WIRELESS), QLatin1String("PropertiesChanged"), this,SLOT(propertiesSwap(QMap))); - - QDBusPendingReply > reply - = asyncCall(QLatin1String("GetAccessPoints")); - - QDBusPendingCallWatcher *callWatcher = new QDBusPendingCallWatcher(reply); - connect(callWatcher, SIGNAL(finished(QDBusPendingCallWatcher*)), - this, SLOT(accessPointsFinished(QDBusPendingCallWatcher*))); } QNetworkManagerInterfaceDeviceWireless::~QNetworkManagerInterfaceDeviceWireless() { -} - -void QNetworkManagerInterfaceDeviceWireless::slotAccessPointAdded(QDBusObjectPath path) -{ - if (path.path().length() > 2) - Q_EMIT accessPointAdded(path.path()); -} - -void QNetworkManagerInterfaceDeviceWireless::slotAccessPointRemoved(QDBusObjectPath path) -{ - if (path.path().length() > 2) - Q_EMIT accessPointRemoved(path.path()); + QDBusConnection::systemBus().disconnect(QLatin1String(NM_DBUS_SERVICE), + path(), + QLatin1String(NM_DBUS_INTERFACE_DEVICE_WIRELESS), + QLatin1String("PropertiesChanged"), + this,SLOT(propertiesSwap(QMap))); } bool QNetworkManagerInterfaceDeviceWireless::setConnections() { - if (!isValid()) - return false; - - QDBusConnection dbusConnection = QDBusConnection::systemBus(); - bool allOk = true; - - if (!dbusConnection.connect(QLatin1String(NM_DBUS_SERVICE), - interfacePath, - QLatin1String(NM_DBUS_INTERFACE_DEVICE_WIRELESS), - QLatin1String("AccessPointAdded"), - this, SLOT(slotAccessPointAdded(QDBusObjectPath)))) { - allOk = false; - } - - - if (!dbusConnection.connect(QLatin1String(NM_DBUS_SERVICE), - interfacePath, - QLatin1String(NM_DBUS_INTERFACE_DEVICE_WIRELESS), - QLatin1String("AccessPointRemoved"), - this, SLOT(slotAccessPointRemoved(QDBusObjectPath)))) { - allOk = false; - } - - if (!dbusConnection.connect(QLatin1String(NM_DBUS_SERVICE), - interfacePath, - QLatin1String(NM_DBUS_INTERFACE_DEVICE_WIRELESS), - QLatin1String("ScanDone"), - this, SLOT(scanIsDone()))) { - allOk = false; - } - return allOk; -} - -void QNetworkManagerInterfaceDeviceWireless::accessPointsFinished(QDBusPendingCallWatcher *watcher) -{ - QDBusPendingReply > reply(*watcher); - watcher->deleteLater(); - if (!reply.isError()) { - accessPointsList = reply.value(); - } - - for (int i = 0; i < accessPointsList.size(); i++) { - Q_EMIT accessPointAdded(accessPointsList.at(i).path()); - } + return true; } QList QNetworkManagerInterfaceDeviceWireless::getAccessPoints() @@ -676,11 +622,6 @@ quint32 QNetworkManagerInterfaceDeviceWireless::wirelessCapabilities() const return 0; } -void QNetworkManagerInterfaceDeviceWireless::scanIsDone() -{ - Q_EMIT scanDone(); -} - void QNetworkManagerInterfaceDeviceWireless::requestScan() { asyncCall(QLatin1String("RequestScan")); @@ -729,6 +670,12 @@ QNetworkManagerInterfaceDeviceModem::QNetworkManagerInterfaceDeviceModem(const Q QNetworkManagerInterfaceDeviceModem::~QNetworkManagerInterfaceDeviceModem() { + QDBusConnection::systemBus().disconnect(QLatin1String(NM_DBUS_SERVICE), + path(), + QLatin1String(NM_DBUS_PATH_SETTINGS), + QLatin1String(NM_DBUS_IFACE_SETTINGS), + QLatin1String("NewConnection"), + this, SIGNAL(newConnection(QDBusObjectPath))); } QNetworkManagerInterfaceDeviceModem::ModemCapabilities QNetworkManagerInterfaceDeviceModem::modemCapabilities() const @@ -833,6 +780,16 @@ QNetworkManagerSettingsConnection::QNetworkManagerSettingsConnection(const QStri QNetworkManagerSettingsConnection::~QNetworkManagerSettingsConnection() { + QDBusConnection::systemBus().disconnect(service(), + path(), + QLatin1String(NM_DBUS_IFACE_SETTINGS_CONNECTION), + QLatin1String("Updated"), + this, SIGNAL(updated())); + QDBusConnection::systemBus().disconnect(service(), + path(), + QLatin1String(NM_DBUS_IFACE_SETTINGS_CONNECTION), + QLatin1String("Removed"), + this, SIGNAL(slotSettingsRemoved())); } bool QNetworkManagerSettingsConnection::setConnections() @@ -989,6 +946,11 @@ QNetworkManagerConnectionActive::QNetworkManagerConnectionActive(const QString & QNetworkManagerConnectionActive::~QNetworkManagerConnectionActive() { + QDBusConnection::systemBus().disconnect(QLatin1String(NM_DBUS_SERVICE), + path(), + QLatin1String(NM_DBUS_INTERFACE_ACTIVE_CONNECTION), + QLatin1String("PropertiesChanged"), + this,SLOT(propertiesSwap(QMap))); } QDBusObjectPath QNetworkManagerConnectionActive::connection() const diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h index 79567057891..4b810caf4a4 100644 --- a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h +++ b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h @@ -322,7 +322,6 @@ public: QObject *parent = 0); ~QNetworkManagerInterfaceDeviceWireless(); - QDBusObjectPath path() const; QList getAccessPoints(); QString hwAddress() const; @@ -335,21 +334,11 @@ public: void requestScan(); Q_SIGNALS: void propertiesChanged(QMap); - void accessPointAdded(const QString &); - void accessPointRemoved(const QString &); - void scanDone(); void propertiesReady(); - void accessPointsReady(); private Q_SLOTS: - void scanIsDone(); void propertiesSwap(QMap); - void slotAccessPointAdded(QDBusObjectPath); - void slotAccessPointRemoved(QDBusObjectPath); - - void accessPointsFinished(QDBusPendingCallWatcher *watcher); - private: QVariantMap propertyMap; QList accessPointsList; From d0012ad64cd6733c072dd18cf82edef4ded32f95 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 18 Aug 2016 14:23:19 +0200 Subject: [PATCH 23/24] Windows style: Scale more native metrics per monitor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix a few places that were overlooked in change 29c6e39086831f6811e94364273c1f4bff119bef. Most notably, fixes MDI subwindow titles disappearing when moving windows between monitors. Task-number: QTBUG-49374 Change-Id: Ie6ffabc4909064e649a3820d9aa952f3991ef06b Reviewed-by: Morten Johan Sørvig --- src/widgets/styles/qwindowsvistastyle.cpp | 11 ++++++----- src/widgets/styles/qwindowsxpstyle.cpp | 22 ++++++++++++---------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/src/widgets/styles/qwindowsvistastyle.cpp b/src/widgets/styles/qwindowsvistastyle.cpp index fe9684a25fc..52006815ede 100644 --- a/src/widgets/styles/qwindowsvistastyle.cpp +++ b/src/widgets/styles/qwindowsvistastyle.cpp @@ -1175,9 +1175,9 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption case CE_MenuItem: if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast(option)) { // windows always has a check column, regardless whether we have an icon or not - const qreal devicePixelRatio = QWindowsXPStylePrivate::devicePixelRatio(widget); - int checkcol = qRound(qreal(25) / devicePixelRatio); - const int gutterWidth = qRound(qreal(3) / devicePixelRatio); + const qreal factor = QWindowsXPStylePrivate::nativeMetricScaleFactor(widget); + int checkcol = qRound(qreal(25) * factor); + const int gutterWidth = qRound(qreal(3) * factor); { XPThemeData theme(widget, 0, QWindowsXPStylePrivate::MenuTheme, MENU_POPUPCHECKBACKGROUND, MBI_HOT); @@ -2166,8 +2166,9 @@ QRect QWindowsVistaStyle::subControlRect(ComplexControl control, const QStyleOpt const bool isToolTitle = false; const int height = tb->rect.height(); const int width = tb->rect.width(); - int buttonWidth = GetSystemMetrics(SM_CXSIZE) / QWindowsStylePrivate::devicePixelRatio(widget) - - int(QStyleHelper::dpiScaled(4)); + const int buttonWidth = + qRound(qreal(GetSystemMetrics(SM_CXSIZE)) * QWindowsStylePrivate::nativeMetricScaleFactor(widget) + - QStyleHelper::dpiScaled(4)); const int frameWidth = proxy()->pixelMetric(PM_MdiSubWindowFrameWidth, option, widget); const bool sysmenuHint = (tb->titleBarFlags & Qt::WindowSystemMenuHint) != 0; diff --git a/src/widgets/styles/qwindowsxpstyle.cpp b/src/widgets/styles/qwindowsxpstyle.cpp index f2ee8e0b47f..30177071179 100644 --- a/src/widgets/styles/qwindowsxpstyle.cpp +++ b/src/widgets/styles/qwindowsxpstyle.cpp @@ -2098,7 +2098,7 @@ void QWindowsXPStyle::drawControl(ControlElement element, const QStyleOption *op themeNumber = QWindowsXPStylePrivate::StatusTheme; partId = SP_GRIPPER; XPThemeData theme(0, p, themeNumber, partId, 0); - QSize size = (theme.size() / QWindowsStylePrivate::devicePixelRatio(widget)).toSize(); + QSize size = (theme.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget)).toSize(); size.rheight()--; if (const QStyleOptionSizeGrip *sg = qstyleoption_cast(option)) { switch (sg->corner) { @@ -2169,7 +2169,7 @@ void QWindowsXPStyle::drawControl(ControlElement element, const QStyleOption *op QWindowsXPStylePrivate::ToolBarTheme, TP_SPLITBUTTONDROPDOWN); if (theme.isValid()) { - const QSize size = (theme.size() / QWindowsStylePrivate::devicePixelRatio(widget)).toSize(); + const QSize size = (theme.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget)).toSize(); mbiw = size.width(); mbih = size.height(); } @@ -2632,10 +2632,11 @@ void QWindowsXPStyle::drawControl(ControlElement element, const QStyleOption *op QRect QWindowsXPStylePrivate::scrollBarGripperBounds(QStyle::State flags, const QWidget *widget, XPThemeData *theme) { const bool horizontal = flags & QStyle::State_Horizontal; - const QMargins contentsMargin = (theme->margins(theme->rect, TMT_SIZINGMARGINS) - / QWindowsStylePrivate::devicePixelRatio(widget)).toMargins(); + const qreal factor = QWindowsStylePrivate::nativeMetricScaleFactor(widget); + const QMargins contentsMargin = + (theme->margins(theme->rect, TMT_SIZINGMARGINS) * factor).toMargins(); theme->partId = horizontal ? SBP_GRIPPERHORZ : SBP_GRIPPERVERT; - const QSize size = (theme->size() / QWindowsStylePrivate::devicePixelRatio(widget)).toSize(); + const QSize size = (theme->size() * factor).toSize(); const int hSpace = theme->rect.width() - size.width(); const int vSpace = theme->rect.height() - size.height(); @@ -3793,12 +3794,13 @@ QSize QWindowsXPStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt { XPThemeData buttontheme(widget, 0, QWindowsXPStylePrivate::ButtonTheme, BP_PUSHBUTTON, PBS_NORMAL); if (buttontheme.isValid()) { - const qreal devicePixelRatio = QWindowsXPStylePrivate::devicePixelRatio(widget); - const QMarginsF borderSize = buttontheme.margins() / devicePixelRatio; + const qreal factor = QWindowsXPStylePrivate::nativeMetricScaleFactor(widget); + const QMarginsF borderSize = buttontheme.margins() * factor; if (!borderSize.isNull()) { - const qreal margin = qreal(2) / devicePixelRatio; + const qreal margin = qreal(2) * factor; sz.rwidth() += qRound(borderSize.left() + borderSize.right() - margin); - sz.rheight() += int(borderSize.bottom() + borderSize.top() - margin + devicePixelRatio - 1); + sz.rheight() += int(borderSize.bottom() + borderSize.top() - margin + + qreal(1) / factor - 1); } const int textMargins = 2*(proxy()->pixelMetric(PM_FocusFrameHMargin) + 1); sz += QSize(qMax(pixelMetric(QStyle::PM_ScrollBarExtent, option, widget) @@ -4072,7 +4074,7 @@ QIcon QWindowsXPStyle::standardIcon(StandardPixmap standardIcon, XPThemeData theme(0, 0, QWindowsXPStylePrivate::WindowTheme, WP_RESTOREBUTTON, RBS_NORMAL); if (theme.isValid()) { - const QSize size = (themeSize.size() / QWindowsStylePrivate::devicePixelRatio(widget)).toSize(); + const QSize size = (themeSize.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget)).toSize(); QPixmap pm(size); pm.fill(Qt::transparent); QPainter p(&pm); From 1e6630b54ce9a005c2cffac4dac95641838e8231 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 12 Jul 2016 09:01:39 +0200 Subject: [PATCH 24/24] Fix crash when exiting while stacked modal dialogs are shown Remove QWindow instance from QGuiApplicationPrivate::modalWindowList in the destructor. Task-number: QTBUG-54566 Change-Id: I1f07fb46a371f69f04907b20657f3b05571445bd Reviewed-by: Marc Mutz Reviewed-by: Gabriel de Dietrich --- src/gui/kernel/qwindow.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 7f84706b6f7..2e212e5fdb0 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -204,6 +204,8 @@ QWindow::~QWindow() { destroy(); QGuiApplicationPrivate::window_list.removeAll(this); + if (!QGuiApplicationPrivate::is_app_closing) + QGuiApplicationPrivate::instance()->modalWindowList.removeOne(this); } void QWindowPrivate::init()