Merge "Merge remote-tracking branch 'origin/5.6' into 5.7" into refs/staging/5.7

This commit is contained in:
Liang Qi 2016-08-25 14:20:33 +00:00 committed by The Qt Project
commit 13680ceb9a
31 changed files with 356 additions and 468 deletions

2
configure vendored
View File

@ -6840,7 +6840,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)

View File

@ -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.

View File

@ -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()
# Extra warnings for Qt non-example code, to ensure cleanliness of the sources.
# The block below may turn these warnings into errors for some Qt targets.

View File

@ -39,7 +39,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

View File

@ -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";
}

View File

@ -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))

View File

@ -62,7 +62,7 @@
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugDocumentVersioning = "NO"
allowLocationSimulation = "YES">
<BuildableProductRunnable>
<BuildableReference
@ -88,7 +88,7 @@
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
debugDocumentVersioning = "NO">
<BuildableProductRunnable>
<BuildableReference
BuildableIdentifier = "primary"

View File

@ -238,15 +238,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();
for (const QString &language : qAsConst(languageList)) {
const QString lang = language == QLatin1String("C") ? QLatin1String("en_US") : language;
const QString comm = d->localeComments.value(lang);

View File

@ -305,12 +305,11 @@ void QFutureInterfaceBase::waitForResult(int resultIndex)
lock.relock();
if (!(d->state & Running))
return;
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();
}

View File

@ -580,34 +580,11 @@ const int FreeListConstants::Sizes[FreeListConstants::BlockCount] = {
typedef QFreeList<QMutexPrivate, FreeListConstants> 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<FreeList> 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()

View File

@ -848,7 +848,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;
@ -857,12 +856,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:

View File

@ -411,7 +411,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
@ -693,8 +693,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
@ -1179,7 +1179,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));
@ -1318,7 +1318,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);
@ -1330,7 +1330,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 {

View File

@ -183,6 +183,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);

View File

@ -210,6 +210,8 @@ QWindow::~QWindow()
{
destroy();
QGuiApplicationPrivate::window_list.removeAll(this);
if (!QGuiApplicationPrivate::is_app_closing)
QGuiApplicationPrivate::instance()->modalWindowList.removeOne(this);
}
void QWindowPrivate::init()

View File

@ -1039,46 +1039,45 @@ QByteArray QFontEngine::getSfntTable(uint tag) const
return table;
}
void QFontEngine::clearGlyphCache(const void *key)
void QFontEngine::clearGlyphCache(const void *context)
{
for (QLinkedList<GlyphCacheEntry>::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<GlyphCacheEntry>::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 void*, GlyphCaches>::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)
@ -1558,12 +1557,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)
{
}
@ -1573,7 +1571,6 @@ QFontEngine::GlyphCacheEntry::~GlyphCacheEntry()
QFontEngine::GlyphCacheEntry &QFontEngine::GlyphCacheEntry::operator=(const GlyphCacheEntry &o)
{
context = o.context;
cache = o.cache;
return *this;
}

View File

@ -357,12 +357,11 @@ private:
GlyphCacheEntry &operator=(const GlyphCacheEntry &);
const void *context;
QExplicitlySharedDataPointer<QFontEngineGlyphCache> 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<GlyphCacheEntry> m_glyphCaches;
typedef QLinkedList<GlyphCacheEntry> GlyphCaches;
mutable QHash<const void *, GlyphCaches> m_glyphCaches;
private:
QVariant m_userData;

View File

@ -129,6 +129,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);
@ -141,14 +144,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();
@ -224,6 +219,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
@ -253,11 +252,6 @@ void QNetworkManagerEngine::requestUpdate()
QMetaObject::invokeMethod(this, "updateCompleted", Qt::QueuedConnection);
}
void QNetworkManagerEngine::scanFinished()
{
QMetaObject::invokeMethod(this, "updateCompleted", Qt::QueuedConnection);
}
void QNetworkManagerEngine::interfacePropertiesChanged(const QMap<QString, QVariant> &properties)
{
QMutexLocker locker(&mutex);
@ -399,57 +393,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<QNetworkManagerInterfaceDeviceWired *>(sender());
@ -540,7 +483,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;
}
}
@ -569,7 +512,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());
}
@ -598,15 +541,10 @@ void QNetworkManagerEngine::removeConnection(const QString &path)
emit configurationRemoved(ptr);
locker.relock();
}
// add base AP back into configurations
QMapIterator<QString, QString> 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()
@ -680,114 +618,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)
{
@ -810,7 +640,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;
}
@ -1080,10 +910,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<QString,QVariant>)),

View File

@ -99,19 +99,12 @@ private Q_SLOTS:
void interfacePropertiesChanged(const QMap<QString, QVariant> &properties);
void activeConnectionPropertiesChanged(const QMap<QString, QVariant> &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());

View File

@ -101,6 +101,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<QString,QVariant>)));
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()
@ -241,28 +256,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<QVariant> argumentList;
argumentList << QLatin1String(NM_DBUS_INTERFACE_ACCESS_POINT);
QDBusPendingReply<QVariantMap> 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<QString,QVariant>)));
}
QNetworkManagerInterfaceAccessPoint::~QNetworkManagerInterfaceAccessPoint()
@ -375,6 +368,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,QVariant>)));
}
QString QNetworkManagerInterfaceDevice::udi() const
@ -474,6 +472,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,QVariant>)));
}
QString QNetworkManagerInterfaceDeviceWired::hwAddress() const
@ -563,77 +566,20 @@ QNetworkManagerInterfaceDeviceWireless::QNetworkManagerInterfaceDeviceWireless(c
QLatin1String(NM_DBUS_INTERFACE_DEVICE_WIRELESS),
QLatin1String("PropertiesChanged"),
this,SLOT(propertiesSwap(QMap<QString,QVariant>)));
QDBusPendingReply<QList<QDBusObjectPath> > 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<QString,QVariant>)));
}
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<QList<QDBusObjectPath> > 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 <QDBusObjectPath> QNetworkManagerInterfaceDeviceWireless::getAccessPoints()
@ -682,11 +628,6 @@ quint32 QNetworkManagerInterfaceDeviceWireless::wirelessCapabilities() const
return 0;
}
void QNetworkManagerInterfaceDeviceWireless::scanIsDone()
{
Q_EMIT scanDone();
}
void QNetworkManagerInterfaceDeviceWireless::requestScan()
{
asyncCall(QLatin1String("RequestScan"));
@ -735,6 +676,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
@ -839,6 +786,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()
@ -995,6 +952,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<QString,QVariant>)));
}
QDBusObjectPath QNetworkManagerConnectionActive::connection() const

View File

@ -328,7 +328,6 @@ public:
QObject *parent = 0);
~QNetworkManagerInterfaceDeviceWireless();
QDBusObjectPath path() const;
QList <QDBusObjectPath> getAccessPoints();
QString hwAddress() const;
@ -341,21 +340,11 @@ public:
void requestScan();
Q_SIGNALS:
void propertiesChanged(QMap<QString,QVariant>);
void accessPointAdded(const QString &);
void accessPointRemoved(const QString &);
void scanDone();
void propertiesReady();
void accessPointsReady();
private Q_SLOTS:
void scanIsDone();
void propertiesSwap(QMap<QString,QVariant>);
void slotAccessPointAdded(QDBusObjectPath);
void slotAccessPointRemoved(QDBusObjectPath);
void accessPointsFinished(QDBusPendingCallWatcher *watcher);
private:
QVariantMap propertyMap;
QList <QDBusObjectPath> accessPointsList;

View File

@ -914,7 +914,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

View File

@ -146,7 +146,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<IDataPackage> package;

View File

@ -198,7 +198,9 @@ void QUrlModel::setUrl(const QModelIndex &index, const QUrl &url, const QModelIn
QIcon newIcon = qvariant_cast<QIcon>(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);

View File

@ -1002,6 +1002,7 @@ QRenderRule::QRenderRule(const QVector<Declaration> &declarations, const QObject
}
}
if (hasBorder()) {
if (const QWidget *widget = qobject_cast<const QWidget *>(object)) {
QStyleSheetStyle *style = const_cast<QStyleSheetStyle *>(globalStyleSheetStyle);
if (!style)
@ -1009,8 +1010,9 @@ QRenderRule::QRenderRule(const QVector<Declaration> &declarations, const QObject
if (style)
fixupBorder(style->nativeFrameWidth(widget));
}
if (hasBorder() && border()->hasBorderImage())
if (border()->hasBorderImage())
defaultBackground = QBrush();
}
}
QRect QRenderRule::borderRect(const QRect& r) const

View File

@ -1181,9 +1181,9 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
case CE_MenuItem:
if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(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);
@ -2172,8 +2172,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;

View File

@ -2106,7 +2106,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<const QStyleOptionSizeGrip *>(option)) {
switch (sg->corner) {
@ -2177,7 +2177,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();
}
@ -2640,10 +2640,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();
@ -3801,12 +3802,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)
@ -4080,7 +4082,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);

View File

@ -464,6 +464,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;
@ -504,6 +517,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

View File

@ -127,6 +127,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";
@ -445,6 +446,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()

View File

@ -55,6 +55,7 @@ private slots:
void listAliases_data();
void listAliases();
void icons();
void comment();
void mimeTypeForFileWithContent();
void mimeTypeForUrl();
void mimeTypeForData_data();

View File

@ -152,12 +152,14 @@ static void dumpConfiguration(QTextStream &str)
}
// On Windows, this will provide addition GPU info similar to the output of dxdiag.
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";
}
}
}
void tst_QOpenGlConfig::testConfiguration()

View File

@ -32,26 +32,22 @@
#include <QOpenGLFunctions>
#include <QPainter>
#include <QElapsedTimer>
#include <QCommandLineParser>
#include <QScreen>
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
@ -64,12 +60,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() {
@ -101,27 +100,52 @@ 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)
{
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 numWindowsOption("numwindows", "Open <N> windows instead of the default 3.", "N", "3");
parser.addOption(numWindowsOption);
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 {
@ -129,36 +153,41 @@ int main(int argc, char **argv)
}
QSurfaceFormat::setDefaultFormat(fmt);
Window w1(0);
if (QGuiApplication::arguments().contains(QLatin1String("--vsyncone"))) {
QRect availableGeometry = app.primaryScreen()->availableGeometry();
int numberOfWindows = qMax(parser.value(numWindowsOption).toInt(), 1);
QList<QWindow *> 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 w1fmt = fmt;
w1fmt.setSwapInterval(1);
w1.setFormat(w1fmt);
QSurfaceFormat vsyncedSurfaceFormat = fmt;
vsyncedSurfaceFormat.setSwapInterval(1);
w->setFormat(vsyncedSurfaceFormat);
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();
QList<QWindow *> extraWindows;
int countIdx;
if ((countIdx = QGuiApplication::arguments().indexOf(QLatin1String("--extrawindows"))) >= 0) {
int extraWindowCount = QGuiApplication::arguments().at(countIdx + 1).toInt();
for (int i = 0; i < extraWindowCount; ++i) {
Window *w = new Window(3 + i);
extraWindows << w;
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;
}
#include "main.moc"