diff options
Diffstat (limited to 'src/plugins')
270 files changed, 2356 insertions, 7026 deletions
diff --git a/src/plugins/bearer/android/jar/jar.pro b/src/plugins/bearer/android/jar/jar.pro index f988019dac..8277a8abc1 100644 --- a/src/plugins/bearer/android/jar/jar.pro +++ b/src/plugins/bearer/android/jar/jar.pro @@ -1,3 +1,5 @@ +CONFIG += single_arch + TARGET = QtAndroidBearer load(qt_build_paths) diff --git a/src/plugins/bearer/connman/qconnmanengine.cpp b/src/plugins/bearer/connman/qconnmanengine.cpp index eabae5a07b..8b2076bd18 100644 --- a/src/plugins/bearer/connman/qconnmanengine.cpp +++ b/src/plugins/bearer/connman/qconnmanengine.cpp @@ -46,6 +46,7 @@ #include <QtNetwork/qnetworksession.h> #include <QtCore/qdebug.h> +#include <QtCore/private/qlocking_p.h> #include <QtDBus/QtDBus> #include <QtDBus/QDBusConnection> @@ -74,13 +75,13 @@ QConnmanEngine::~QConnmanEngine() bool QConnmanEngine::connmanAvailable() const { - QMutexLocker locker(&mutex); + const auto locker = qt_scoped_lock(mutex); return connmanManager->isValid(); } void QConnmanEngine::initialize() { - QMutexLocker locker(&mutex); + const auto locker = qt_scoped_lock(mutex); connect(ofonoManager,SIGNAL(modemChanged()),this,SLOT(changedModem())); ofonoNetwork = new QOfonoNetworkRegistrationInterface(ofonoManager->currentModem(),this); @@ -101,7 +102,7 @@ void QConnmanEngine::initialize() void QConnmanEngine::changedModem() { - QMutexLocker locker(&mutex); + const auto locker = qt_scoped_lock(mutex); if (ofonoNetwork) delete ofonoNetwork; @@ -114,7 +115,7 @@ void QConnmanEngine::changedModem() void QConnmanEngine::servicesReady(const QStringList &list) { - QMutexLocker locker(&mutex); + const auto locker = qt_scoped_lock(mutex); for (const QString &servPath : list) addServiceConfiguration(servPath); @@ -123,7 +124,7 @@ void QConnmanEngine::servicesReady(const QStringList &list) QList<QNetworkConfigurationPrivate *> QConnmanEngine::getConfigurations() { - QMutexLocker locker(&mutex); + const auto locker = qt_scoped_lock(mutex); QList<QNetworkConfigurationPrivate *> fetchedConfigurations; QNetworkConfigurationPrivate* cpPriv = 0; const int numFoundConfigurations = foundConfigurations.count(); @@ -150,19 +151,19 @@ QList<QNetworkConfigurationPrivate *> QConnmanEngine::getConfigurations() QString QConnmanEngine::getInterfaceFromId(const QString &id) { - QMutexLocker locker(&mutex); + const auto locker = qt_scoped_lock(mutex); return configInterfaces.value(id); } bool QConnmanEngine::hasIdentifier(const QString &id) { - QMutexLocker locker(&mutex); + const auto locker = qt_scoped_lock(mutex); return accessPointConfigurations.contains(id); } void QConnmanEngine::connectToId(const QString &id) { - QMutexLocker locker(&mutex); + const auto locker = qt_scoped_lock(mutex); QConnmanServiceInterface *serv = connmanServiceInterfaces.value(id); @@ -184,7 +185,7 @@ void QConnmanEngine::connectToId(const QString &id) void QConnmanEngine::disconnectFromId(const QString &id) { - QMutexLocker locker(&mutex); + const auto locker = qt_scoped_lock(mutex); QConnmanServiceInterface *serv = connmanServiceInterfaces.value(id); if (!serv || !serv->isValid()) { @@ -196,7 +197,7 @@ void QConnmanEngine::disconnectFromId(const QString &id) void QConnmanEngine::requestUpdate() { - QMutexLocker locker(&mutex); + const auto locker = qt_scoped_lock(mutex); QTimer::singleShot(0, this, SLOT(doRequestUpdate())); } @@ -215,7 +216,7 @@ void QConnmanEngine::finishedScan(bool error) void QConnmanEngine::updateServices(const ConnmanMapList &changed, const QList<QDBusObjectPath> &removed) { - QMutexLocker locker(&mutex); + const auto locker = qt_scoped_lock(mutex); foreach (const QDBusObjectPath &objectPath, removed) { removeConfiguration(objectPath.path()); @@ -234,7 +235,7 @@ void QConnmanEngine::updateServices(const ConnmanMapList &changed, const QList<Q QNetworkSession::State QConnmanEngine::sessionStateForId(const QString &id) { - QMutexLocker locker(&mutex); + const auto locker = qt_scoped_lock(mutex); QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id); @@ -275,7 +276,7 @@ QNetworkSession::State QConnmanEngine::sessionStateForId(const QString &id) quint64 QConnmanEngine::bytesWritten(const QString &id) {//TODO use connman counter API - QMutexLocker locker(&mutex); + const auto locker = qt_scoped_lock(mutex); quint64 result = 0; QString devFile = getInterfaceFromId(id); QFile tx("/sys/class/net/"+devFile+"/statistics/tx_bytes"); @@ -290,7 +291,7 @@ quint64 QConnmanEngine::bytesWritten(const QString &id) quint64 QConnmanEngine::bytesReceived(const QString &id) {//TODO use connman counter API - QMutexLocker locker(&mutex); + const auto locker = qt_scoped_lock(mutex); quint64 result = 0; QString devFile = getInterfaceFromId(id); QFile rx("/sys/class/net/"+devFile+"/statistics/rx_bytes"); @@ -305,7 +306,7 @@ quint64 QConnmanEngine::bytesReceived(const QString &id) quint64 QConnmanEngine::startTime(const QString &/*id*/) { // TODO - QMutexLocker locker(&mutex); + const auto locker = qt_scoped_lock(mutex); if (activeTime.isNull()) { return 0; } @@ -327,7 +328,7 @@ QNetworkSessionPrivate *QConnmanEngine::createSessionBackend() QNetworkConfigurationPrivatePointer QConnmanEngine::defaultConfiguration() { - const QMutexLocker locker(&mutex); + const auto locker = qt_scoped_lock(mutex); const auto servPaths = connmanManager->getServices(); for (const QString &servPath : servPaths) { if (connmanServiceInterfaces.contains(servPath)) { @@ -352,7 +353,7 @@ void QConnmanEngine::configurationChange(QConnmanServiceInterface *serv) { if (!serv) return; - QMutexLocker locker(&mutex); + auto locker = qt_unique_lock(mutex); QString id = serv->path(); if (accessPointConfigurations.contains(id)) { @@ -381,7 +382,7 @@ void QConnmanEngine::configurationChange(QConnmanServiceInterface *serv) if (changed) { locker.unlock(); emit configurationChanged(ptr); - locker.relock(); + locker.lock(); } } @@ -391,7 +392,7 @@ void QConnmanEngine::configurationChange(QConnmanServiceInterface *serv) QNetworkConfiguration::StateFlags QConnmanEngine::getStateForService(const QString &service) { - QMutexLocker locker(&mutex); + const auto locker = qt_scoped_lock(mutex); QConnmanServiceInterface *serv = connmanServiceInterfaces.value(service); if (!serv) return QNetworkConfiguration::Undefined; @@ -472,7 +473,7 @@ bool QConnmanEngine::isRoamingAllowed(const QString &context) void QConnmanEngine::removeConfiguration(const QString &id) { - QMutexLocker locker(&mutex); + auto locker = qt_unique_lock(mutex); if (accessPointConfigurations.contains(id)) { @@ -485,13 +486,12 @@ void QConnmanEngine::removeConfiguration(const QString &id) foundConfigurations.removeOne(ptr.data()); locker.unlock(); emit configurationRemoved(ptr); - locker.relock(); } } void QConnmanEngine::addServiceConfiguration(const QString &servicePath) { - QMutexLocker locker(&mutex); + auto locker = qt_unique_lock(mutex); if (!connmanServiceInterfaces.contains(servicePath)) { QConnmanServiceInterface *serv = new QConnmanServiceInterface(servicePath, this); connmanServiceInterfaces.insert(serv->path(),serv); @@ -547,7 +547,6 @@ void QConnmanEngine::addServiceConfiguration(const QString &servicePath) locker.unlock(); Q_EMIT configurationAdded(ptr); - locker.relock(); } } diff --git a/src/plugins/bearer/connman/qconnmanengine.h b/src/plugins/bearer/connman/qconnmanengine.h index c9ff17f801..ef80d38fa2 100644 --- a/src/plugins/bearer/connman/qconnmanengine.h +++ b/src/plugins/bearer/connman/qconnmanengine.h @@ -68,7 +68,7 @@ class QConnmanEngine : public QBearerEngineImpl Q_OBJECT public: - QConnmanEngine(QObject *parent = 0); + QConnmanEngine(QObject *parent = nullptr); ~QConnmanEngine(); bool connmanAvailable() const; diff --git a/src/plugins/bearer/connman/qconnmanservice_linux.cpp b/src/plugins/bearer/connman/qconnmanservice_linux.cpp index 3659eb7740..35d9c40680 100644 --- a/src/plugins/bearer/connman/qconnmanservice_linux.cpp +++ b/src/plugins/bearer/connman/qconnmanservice_linux.cpp @@ -80,8 +80,7 @@ QConnmanManagerInterface::QConnmanManagerInterface( QObject *parent) qDBusRegisterMetaType<ConnmanMap>(); qDBusRegisterMetaType<ConnmanMapList>(); - QList<QVariant> argumentList; - QDBusPendingReply<QVariantMap> props_reply = asyncCallWithArgumentList(QLatin1String("GetProperties"), argumentList); + QDBusPendingReply<QVariantMap> props_reply = asyncCall(QLatin1String("GetProperties")); QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(props_reply, this); QObject::connect(watcher,SIGNAL(finished(QDBusPendingCallWatcher*)), @@ -106,8 +105,7 @@ QConnmanManagerInterface::QConnmanManagerInterface( QObject *parent) QLatin1String("TechnologyRemoved"), this,SLOT(technologyRemoved(QDBusObjectPath))); - QList<QVariant> argumentList2; - QDBusPendingReply<ConnmanMapList> serv_reply = asyncCallWithArgumentList(QLatin1String("GetServices"), argumentList2); + QDBusPendingReply<ConnmanMapList> serv_reply = asyncCall(QLatin1String("GetServices")); QDBusPendingCallWatcher *watcher2 = new QDBusPendingCallWatcher(serv_reply, this); QObject::connect(watcher2,SIGNAL(finished(QDBusPendingCallWatcher*)), @@ -289,8 +287,7 @@ QConnmanServiceInterface::QConnmanServiceInterface(const QString &dbusPathName,Q CONNMAN_SERVICE_INTERFACE, QDBusConnection::systemBus(), parent) { - QList<QVariant> argumentList; - QDBusPendingReply<QVariantMap> props_reply = asyncCallWithArgumentList(QLatin1String("GetProperties"), argumentList); + QDBusPendingReply<QVariantMap> props_reply = asyncCall(QLatin1String("GetProperties")); QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(props_reply, this); diff --git a/src/plugins/bearer/connman/qconnmanservice_linux_p.h b/src/plugins/bearer/connman/qconnmanservice_linux_p.h index d2804ebca6..790325f9a1 100644 --- a/src/plugins/bearer/connman/qconnmanservice_linux_p.h +++ b/src/plugins/bearer/connman/qconnmanservice_linux_p.h @@ -105,7 +105,7 @@ class QConnmanManagerInterface : public QDBusAbstractInterface public: - QConnmanManagerInterface( QObject *parent = 0); + QConnmanManagerInterface( QObject *parent = nullptr); ~QConnmanManagerInterface(); QDBusObjectPath path() const; @@ -155,7 +155,7 @@ class QConnmanServiceInterface : public QDBusAbstractInterface public: - explicit QConnmanServiceInterface(const QString &dbusPathName,QObject *parent = 0); + explicit QConnmanServiceInterface(const QString &dbusPathName,QObject *parent = nullptr); ~QConnmanServiceInterface(); QVariantMap getProperties(); @@ -202,7 +202,7 @@ class QConnmanTechnologyInterface : public QDBusAbstractInterface public: - explicit QConnmanTechnologyInterface(const QString &dbusPathName,QObject *parent = 0); + explicit QConnmanTechnologyInterface(const QString &dbusPathName,QObject *parent = nullptr); ~QConnmanTechnologyInterface(); QString type(); diff --git a/src/plugins/bearer/corewlan/qcorewlanengine.h b/src/plugins/bearer/corewlan/qcorewlanengine.h index 4a431b886e..6dddee66a4 100644 --- a/src/plugins/bearer/corewlan/qcorewlanengine.h +++ b/src/plugins/bearer/corewlan/qcorewlanengine.h @@ -122,9 +122,9 @@ public: QString interfaceName; QMap<QString, QString> configurationInterface; void getUserConfigurations(); - QString getNetworkNameFromSsid(const QString &ssid); - QString getSsidFromNetworkName(const QString &name); - bool isKnownSsid(const QString &ssid); + QString getNetworkNameFromSsid(const QString &ssid) const; + QString getSsidFromNetworkName(const QString &name) const; + bool isKnownSsid(const QString &ssid) const; QMap<QString, QMap<QString,QString> > userProfiles; signals: @@ -135,7 +135,7 @@ protected: private: QList<QNetworkConfigurationPrivate *> fetchedConfigurations; - QMutex mutex; + mutable QMutex mutex; QStringList foundNetwork(const QString &id, const QString &ssid, const QNetworkConfiguration::StateFlags state, const QString &interfaceName, const QNetworkConfiguration::Purpose purpose); }; diff --git a/src/plugins/bearer/corewlan/qcorewlanengine.mm b/src/plugins/bearer/corewlan/qcorewlanengine.mm index c3dd49ff3e..66f2ed017b 100644 --- a/src/plugins/bearer/corewlan/qcorewlanengine.mm +++ b/src/plugins/bearer/corewlan/qcorewlanengine.mm @@ -62,12 +62,11 @@ extern "C" { // Otherwise it won't find CWKeychain* symbols at link time #include <ifaddrs.h> @interface QT_MANGLE_NAMESPACE(QNSListener) : NSObject <CWEventDelegate> - @property (assign) QCoreWlanEngine* engine; - @end +QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSListener); -@implementation QT_MANGLE_NAMESPACE(QNSListener) { +@implementation QNSListener { NSNotificationCenter *notificationCenter; CWWiFiClient *client; QCoreWlanEngine *engine; @@ -88,7 +87,7 @@ extern "C" { // Otherwise it won't find CWKeychain* symbols at link time return self; } -static QT_MANGLE_NAMESPACE(QNSListener) *listener = 0; +static QNSListener *listener = 0; -(void)dealloc { @@ -203,9 +202,7 @@ void QScanThread::run() } } // add known configurations that are not around. - QMapIterator<QString, QMap<QString,QString> > i(userProfiles); - while (i.hasNext()) { - i.next(); + for (auto i = userProfiles.cbegin(), end = userProfiles.cend(); i != end; ++i) { QString networkName = i.key(); const QString id = QString::number(qHash(QLatin1String("corewlan:") + networkName)); @@ -215,11 +212,8 @@ void QScanThread::run() const QString ssidId = QString::number(qHash(QLatin1String("corewlan:") + networkSsid)); QNetworkConfiguration::StateFlags state = QNetworkConfiguration::Undefined; QString interfaceName; - QMapIterator<QString, QString> ij(i.value()); - while (ij.hasNext()) { - ij.next(); - interfaceName = ij.value(); - } + if (!i.value().isEmpty()) + interfaceName = i.value().last(); if (currentInterfaceServiceActive) { if (networkSsid == QString::fromNSString([currentInterface ssid])) { @@ -269,11 +263,7 @@ QStringList QScanThread::foundNetwork(const QString &id, const QString &name, co QList<QNetworkConfigurationPrivate *> QScanThread::getConfigurations() { QMutexLocker locker(&mutex); - - QList<QNetworkConfigurationPrivate *> foundConfigurations = fetchedConfigurations; - fetchedConfigurations.clear(); - - return foundConfigurations; + return qExchange(fetchedConfigurations, {}); } void QScanThread::getUserConfigurations() @@ -363,17 +353,12 @@ void QScanThread::getUserConfigurations() } } -QString QScanThread::getSsidFromNetworkName(const QString &name) +QString QScanThread::getSsidFromNetworkName(const QString &name) const { QMutexLocker locker(&mutex); - QMapIterator<QString, QMap<QString,QString> > i(userProfiles); - while (i.hasNext()) { - i.next(); - QMap<QString,QString> map = i.value(); - QMapIterator<QString, QString> ij(i.value()); - while (ij.hasNext()) { - ij.next(); + for (auto i = userProfiles.cbegin(), end = userProfiles.cend(); i != end; ++i) { + for (auto ij = i.value().cbegin(), end = i.value().cend(); ij != end; ++ij) { const QString networkNameHash = QString::number(qHash(QLatin1String("corewlan:") +i.key())); if(name == i.key() || name == networkNameHash) { return ij.key(); @@ -383,36 +368,24 @@ QString QScanThread::getSsidFromNetworkName(const QString &name) return QString(); } -QString QScanThread::getNetworkNameFromSsid(const QString &ssid) +QString QScanThread::getNetworkNameFromSsid(const QString &ssid) const { QMutexLocker locker(&mutex); - QMapIterator<QString, QMap<QString,QString> > i(userProfiles); - while (i.hasNext()) { - i.next(); - QMap<QString,QString> map = i.value(); - QMapIterator<QString, QString> ij(i.value()); - while (ij.hasNext()) { - ij.next(); - if(ij.key() == ssid) { - return i.key(); - } - } + for (auto i = userProfiles.cbegin(), end = userProfiles.cend(); i != end; ++i) { + if (i.value().contains(ssid)) + return i.key(); } return QString(); } -bool QScanThread::isKnownSsid(const QString &ssid) +bool QScanThread::isKnownSsid(const QString &ssid) const { QMutexLocker locker(&mutex); - QMapIterator<QString, QMap<QString,QString> > i(userProfiles); - while (i.hasNext()) { - i.next(); - QMap<QString,QString> map = i.value(); - if(map.keys().contains(ssid)) { + for (auto i = userProfiles.cbegin(), end = userProfiles.cend(); i != end; ++i) { + if (i.value().contains(ssid)) return true; - } } return false; } @@ -430,8 +403,7 @@ QCoreWlanEngine::~QCoreWlanEngine() { scanThread->wait(); - while (!foundConfigurations.isEmpty()) - delete foundConfigurations.takeFirst(); + qDeleteAll(qExchange(foundConfigurations, {})); [listener remove]; [listener release]; } @@ -442,7 +414,7 @@ void QCoreWlanEngine::initialize() QMacAutoReleasePool pool; if ([[CWWiFiClient interfaceNames] count] > 0 && !listener) { - listener = [[QT_MANGLE_NAMESPACE(QNSListener) alloc] init]; + listener = [QNSListener alloc] init]; listener.engine = this; hasWifi = true; } else { @@ -486,9 +458,7 @@ void QCoreWlanEngine::connectToId(const QString &id) const QString idHash2 = QString::number(qHash(QLatin1String("corewlan:") + scanThread->getNetworkNameFromSsid(ptr->name))); QString wantedNetwork; - QMapIterator<QString, QMap<QString, QString> > i(scanThread->userProfiles); - while (i.hasNext()) { - i.next(); + for (auto i = scanThread->userProfiles.cbegin(), end = scanThread->userProfiles.cend(); i != end; ++i) { wantedNetwork = i.key(); const QString networkNameHash = QString::number(qHash(QLatin1String("corewlan:") + wantedNetwork)); if (id == networkNameHash) { diff --git a/src/plugins/bearer/generic/qgenericengine.h b/src/plugins/bearer/generic/qgenericengine.h index 08960d66f6..79c71ca7a3 100644 --- a/src/plugins/bearer/generic/qgenericengine.h +++ b/src/plugins/bearer/generic/qgenericengine.h @@ -55,7 +55,7 @@ class QGenericEngine : public QBearerEngineImpl Q_OBJECT public: - QGenericEngine(QObject *parent = 0); + QGenericEngine(QObject *parent = nullptr); ~QGenericEngine(); QString getInterfaceFromId(const QString &id) override; diff --git a/src/plugins/bearer/linux_common/qofonoservice_linux.cpp b/src/plugins/bearer/linux_common/qofonoservice_linux.cpp index 5d72731bc4..05f9b3ca17 100644 --- a/src/plugins/bearer/linux_common/qofonoservice_linux.cpp +++ b/src/plugins/bearer/linux_common/qofonoservice_linux.cpp @@ -99,8 +99,7 @@ QOfonoManagerInterface::~QOfonoManagerInterface() QStringList QOfonoManagerInterface::getModems() { if (modemList.isEmpty()) { - QList<QVariant> argumentList; - QDBusPendingReply<PathPropertiesList> reply = callWithArgumentList(QDBus::Block, QLatin1String("GetModems"), argumentList); + QDBusPendingReply<PathPropertiesList> reply = call(QDBus::Block, QLatin1String("GetModems")); reply.waitForFinished(); if (!reply.isError()) { const auto modems = reply.value(); @@ -184,8 +183,7 @@ QStringList QOfonoModemInterface::interfaces() QVariantMap QOfonoModemInterface::getProperties() { if (propertiesMap.isEmpty()) { - QList<QVariant> argumentList; - QDBusPendingReply<QVariantMap> reply = callWithArgumentList(QDBus::Block, QLatin1String("GetProperties"), argumentList); + QDBusPendingReply<QVariantMap> reply = call(QDBus::Block, QLatin1String("GetProperties")); if (!reply.isError()) { propertiesMap = reply.value(); } @@ -233,8 +231,7 @@ QVariant QOfonoNetworkRegistrationInterface::getProperty(const QString &property QVariantMap QOfonoNetworkRegistrationInterface::getProperties() { if (propertiesMap.isEmpty()) { - QList<QVariant> argumentList; - QDBusPendingReply<QVariantMap> reply = callWithArgumentList(QDBus::Block, QLatin1String("GetProperties"), argumentList); + QDBusPendingReply<QVariantMap> reply = call(QDBus::Block, QLatin1String("GetProperties")); reply.waitForFinished(); if (!reply.isError()) { propertiesMap = reply.value(); @@ -306,8 +303,7 @@ QVariant QOfonoDataConnectionManagerInterface::getProperty(const QString &proper QVariantMap &QOfonoDataConnectionManagerInterface::getProperties() { if (propertiesMap.isEmpty()) { - QList<QVariant> argumentList; - QDBusPendingReply<QVariantMap> reply = callWithArgumentList(QDBus::Block, QLatin1String("GetProperties"), argumentList); + QDBusPendingReply<QVariantMap> reply = call(QDBus::Block, QLatin1String("GetProperties")); if (!reply.isError()) { propertiesMap = reply.value(); } @@ -343,8 +339,7 @@ QOfonoConnectionContextInterface::~QOfonoConnectionContextInterface() QVariantMap QOfonoConnectionContextInterface::getProperties() { if (propertiesMap.isEmpty()) { - QList<QVariant> argumentList; - QDBusPendingReply<QVariantMap> reply = callWithArgumentList(QDBus::Block, QLatin1String("GetProperties"), argumentList); + QDBusPendingReply<QVariantMap> reply = call(QDBus::Block, QLatin1String("GetProperties")); if (!reply.isError()) { propertiesMap = reply.value(); } diff --git a/src/plugins/bearer/linux_common/qofonoservice_linux_p.h b/src/plugins/bearer/linux_common/qofonoservice_linux_p.h index 35614a20f2..62df5d4fa7 100644 --- a/src/plugins/bearer/linux_common/qofonoservice_linux_p.h +++ b/src/plugins/bearer/linux_common/qofonoservice_linux_p.h @@ -100,7 +100,7 @@ class QOfonoManagerInterface : public QDBusAbstractInterface public: - QOfonoManagerInterface( QObject *parent = 0); + QOfonoManagerInterface( QObject *parent = nullptr); ~QOfonoManagerInterface(); QStringList getModems(); @@ -120,7 +120,7 @@ class QOfonoModemInterface : public QDBusAbstractInterface public: - explicit QOfonoModemInterface(const QString &dbusModemPathName, QObject *parent = 0); + explicit QOfonoModemInterface(const QString &dbusModemPathName, QObject *parent = nullptr); ~QOfonoModemInterface(); bool isPowered(); @@ -140,7 +140,7 @@ class QOfonoNetworkRegistrationInterface : public QDBusAbstractInterface public: - explicit QOfonoNetworkRegistrationInterface(const QString &dbusModemPathName, QObject *parent = 0); + explicit QOfonoNetworkRegistrationInterface(const QString &dbusModemPathName, QObject *parent = nullptr); ~QOfonoNetworkRegistrationInterface(); QString getTechnology(); @@ -159,7 +159,7 @@ class QOfonoDataConnectionManagerInterface : public QDBusAbstractInterface public: - explicit QOfonoDataConnectionManagerInterface(const QString &dbusPathName, QObject *parent = 0); + explicit QOfonoDataConnectionManagerInterface(const QString &dbusPathName, QObject *parent = nullptr); ~QOfonoDataConnectionManagerInterface(); QStringList contexts(); @@ -184,7 +184,7 @@ class QOfonoConnectionContextInterface : public QDBusAbstractInterface public: - explicit QOfonoConnectionContextInterface(const QString &dbusPathName, QObject *parent = 0); + explicit QOfonoConnectionContextInterface(const QString &dbusPathName, QObject *parent = nullptr); ~QOfonoConnectionContextInterface(); QVariant getProperty(const QString &); diff --git a/src/plugins/bearer/nativewifi/qnativewifiengine.cpp b/src/plugins/bearer/nativewifi/qnativewifiengine.cpp index bb43072aba..777b4eea59 100644 --- a/src/plugins/bearer/nativewifi/qnativewifiengine.cpp +++ b/src/plugins/bearer/nativewifi/qnativewifiengine.cpp @@ -45,6 +45,7 @@ #include <QtCore/qstringlist.h> #include <QtCore/qcoreapplication.h> +#include <QtCore/qoperatingsystemversion.h> #include <QtCore/qdebug.h> @@ -612,7 +613,8 @@ bool QNativeWifiEngine::requiresPolling() const { // On Windows XP SP2 and SP3 only connection and disconnection notifications are available. // We need to poll for changes in available wireless networks. - return QSysInfo::WindowsVersion <= QSysInfo::WV_2003; + return QOperatingSystemVersion::current() + <= QOperatingSystemVersion(QOperatingSystemVersion::Windows, 5, 2); } QT_END_NAMESPACE diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.h b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.h index 74fe24b5ab..a95c68abdf 100644 --- a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.h +++ b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.h @@ -69,7 +69,7 @@ class QNetworkManagerEngine : public QBearerEngineImpl Q_OBJECT public: - QNetworkManagerEngine(QObject *parent = 0); + QNetworkManagerEngine(QObject *parent = nullptr); ~QNetworkManagerEngine(); bool networkManagerAvailable() const; @@ -99,7 +99,7 @@ private Q_SLOTS: void interfacePropertiesChanged(const QMap<QString, QVariant> &properties); void activeConnectionPropertiesChanged(const QMap<QString, QVariant> &properties); - void newConnection(const QDBusObjectPath &path, QNetworkManagerSettings *settings = 0); + void newConnection(const QDBusObjectPath &path, QNetworkManagerSettings *settings = nullptr); void removeConnection(const QString &path); void updateConnection(); void activationFinished(QDBusPendingCallWatcher *watcher); diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp index 3e77580015..35199eb7a2 100644 --- a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp +++ b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp @@ -72,11 +72,9 @@ QNetworkManagerInterface::QNetworkManagerInterface(QObject *parent) QLatin1String(NM_DBUS_PATH), DBUS_PROPERTIES_INTERFACE, QDBusConnection::systemBus()); - QList<QVariant> argumentList; - argumentList << QLatin1String(NM_DBUS_INTERFACE); QDBusPendingReply<QVariantMap> propsReply - = managerPropertiesInterface.callWithArgumentList(QDBus::Block,QLatin1String("GetAll"), - argumentList); + = managerPropertiesInterface.call(QDBus::Block, QLatin1String("GetAll"), QLatin1String(NM_DBUS_INTERFACE)); + if (!propsReply.isError()) { propertyMap = propsReply.value(); } else { @@ -344,11 +342,8 @@ QNetworkManagerInterfaceDevice::QNetworkManagerInterfaceDevice(const QString &de DBUS_PROPERTIES_INTERFACE, QDBusConnection::systemBus(),parent); - QList<QVariant> argumentList; - argumentList << QLatin1String(NM_DBUS_INTERFACE_DEVICE); QDBusPendingReply<QVariantMap> propsReply - = devicePropertiesInterface.callWithArgumentList(QDBus::Block,QLatin1String("GetAll"), - argumentList); + = devicePropertiesInterface.call(QDBus::Block, QLatin1String("GetAll"), QLatin1String(NM_DBUS_INTERFACE_DEVICE)); if (!propsReply.isError()) { propertyMap = propsReply.value(); @@ -446,11 +441,8 @@ QNetworkManagerInterfaceDeviceWired::QNetworkManagerInterfaceDeviceWired(const Q DBUS_PROPERTIES_INTERFACE, QDBusConnection::systemBus(),parent); - QList<QVariant> argumentList; - argumentList << QLatin1String(NM_DBUS_INTERFACE_DEVICE_WIRED); QDBusPendingReply<QVariantMap> propsReply - = deviceWiredPropertiesInterface.callWithArgumentList(QDBus::Block,QLatin1String("GetAll"), - argumentList); + = deviceWiredPropertiesInterface.call(QDBus::Block, QLatin1String("GetAll"), QLatin1String(NM_DBUS_INTERFACE_DEVICE_WIRED)); if (!propsReply.isError()) { propertyMap = propsReply.value(); @@ -543,11 +535,9 @@ QNetworkManagerInterfaceDeviceWireless::QNetworkManagerInterfaceDeviceWireless(c DBUS_PROPERTIES_INTERFACE, QDBusConnection::systemBus(),parent); - QList<QVariant> argumentList; - argumentList << QLatin1String(NM_DBUS_INTERFACE_DEVICE_WIRELESS); QDBusPendingReply<QVariantMap> propsReply - = deviceWirelessPropertiesInterface.callWithArgumentList(QDBus::Block,QLatin1String("GetAll"), - argumentList); + = deviceWirelessPropertiesInterface.call(QDBus::Block, QLatin1String("GetAll"), QLatin1String(NM_DBUS_INTERFACE_DEVICE_WIRELESS)); + if (!propsReply.isError()) { propertyMap = propsReply.value(); } @@ -647,11 +637,9 @@ QNetworkManagerInterfaceDeviceModem::QNetworkManagerInterfaceDeviceModem(const Q QLatin1String("org.freedesktop.DBus.Properties"), QDBusConnection::systemBus(),parent); - QList<QVariant> argumentList; - argumentList << QLatin1String(NM_DBUS_INTERFACE_DEVICE_MODEM); QDBusPendingReply<QVariantMap> propsReply - = deviceModemPropertiesInterface.callWithArgumentList(QDBus::Block,QLatin1String("GetAll"), - argumentList); + = deviceModemPropertiesInterface.call(QDBus::Block, QLatin1String("GetAll"), QLatin1String(NM_DBUS_INTERFACE_DEVICE_MODEM)); + if (!propsReply.isError()) { propertyMap = propsReply.value(); } @@ -746,9 +734,7 @@ QList <QDBusObjectPath> QNetworkManagerSettings::listConnections() QString QNetworkManagerSettings::getConnectionByUuid(const QString &uuid) { - QList<QVariant> argumentList; - argumentList << QVariant::fromValue(uuid); - QDBusReply<QDBusObjectPath > reply = callWithArgumentList(QDBus::Block,QLatin1String("GetConnectionByUuid"), argumentList); + QDBusReply<QDBusObjectPath > reply = call(QDBus::Block, QLatin1String("GetConnectionByUuid"), uuid); return reply.value().path(); } @@ -917,11 +903,8 @@ QNetworkManagerConnectionActive::QNetworkManagerConnectionActive(const QString & QDBusConnection::systemBus()); - QList<QVariant> argumentList; - argumentList << QLatin1String(NM_DBUS_INTERFACE_ACTIVE_CONNECTION); QDBusPendingReply<QVariantMap> propsReply - = connectionActivePropertiesInterface.callWithArgumentList(QDBus::Block,QLatin1String("GetAll"), - argumentList); + = connectionActivePropertiesInterface.call(QDBus::Block, QLatin1String("GetAll"), QLatin1String(NM_DBUS_INTERFACE_ACTIVE_CONNECTION)); if (!propsReply.isError()) { propertyMap = propsReply.value(); diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h index c879083faf..bff7a71097 100644 --- a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h +++ b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h @@ -152,7 +152,7 @@ public: NM_STATE_CONNECTED_GLOBAL = 70 } NMState; - QNetworkManagerInterface(QObject *parent = 0); + QNetworkManagerInterface(QObject *parent = nullptr); ~QNetworkManagerInterface(); QList <QDBusObjectPath> getDevices(); @@ -228,7 +228,7 @@ public: Q_DECLARE_FLAGS(ApSecurityFlags, ApSecurityFlag) - explicit QNetworkManagerInterfaceAccessPoint(const QString &dbusPathName, QObject *parent = 0); + explicit QNetworkManagerInterfaceAccessPoint(const QString &dbusPathName, QObject *parent = nullptr); ~QNetworkManagerInterfaceAccessPoint(); quint32 flags() const; @@ -259,7 +259,7 @@ class QNetworkManagerInterfaceDevice : public QDBusAbstractInterface public: - explicit QNetworkManagerInterfaceDevice(const QString &deviceObjectPath, QObject *parent = 0); + explicit QNetworkManagerInterfaceDevice(const QString &deviceObjectPath, QObject *parent = nullptr); ~QNetworkManagerInterfaceDevice(); QString udi() const; @@ -288,7 +288,7 @@ class QNetworkManagerInterfaceDeviceWired : public QDBusAbstractInterface public: explicit QNetworkManagerInterfaceDeviceWired(const QString &ifaceDevicePath, - QObject *parent = 0); + QObject *parent = nullptr); ~QNetworkManagerInterfaceDeviceWired(); QString hwAddress() const; @@ -325,7 +325,7 @@ public: }; explicit QNetworkManagerInterfaceDeviceWireless(const QString &ifaceDevicePath, - QObject *parent = 0); + QObject *parent = nullptr); ~QNetworkManagerInterfaceDeviceWireless(); QList <QDBusObjectPath> getAccessPoints(); @@ -367,7 +367,7 @@ public: Q_DECLARE_FLAGS(ModemCapabilities, ModemCapability) explicit QNetworkManagerInterfaceDeviceModem(const QString &ifaceDevicePath, - QObject *parent = 0); + QObject *parent = nullptr); ~QNetworkManagerInterfaceDeviceModem(); ModemCapabilities modemCapabilities() const; @@ -392,7 +392,7 @@ class QNetworkManagerSettings : public QDBusAbstractInterface public: - explicit QNetworkManagerSettings(const QString &settingsService, QObject *parent = 0); + explicit QNetworkManagerSettings(const QString &settingsService, QObject *parent = nullptr); ~QNetworkManagerSettings(); QList <QDBusObjectPath> listConnections(); @@ -413,7 +413,7 @@ class QNetworkManagerSettingsConnection : public QDBusAbstractInterface public: - QNetworkManagerSettingsConnection(const QString &settingsService, const QString &connectionObjectPath, QObject *parent = 0); + QNetworkManagerSettingsConnection(const QString &settingsService, const QString &connectionObjectPath, QObject *parent = nullptr); ~QNetworkManagerSettingsConnection(); QNmSettingsMap getSettings(); @@ -451,7 +451,7 @@ public: Activated = 2 }; - explicit QNetworkManagerConnectionActive(const QString &dbusPathName, QObject *parent = 0); + explicit QNetworkManagerConnectionActive(const QString &dbusPathName, QObject *parent = nullptr); ~ QNetworkManagerConnectionActive(); QDBusObjectPath connection() const; @@ -478,7 +478,7 @@ class QNetworkManagerIp4Config : public QDBusAbstractInterface Q_OBJECT public: - explicit QNetworkManagerIp4Config(const QString &dbusPathName, QObject *parent = 0); + explicit QNetworkManagerIp4Config(const QString &dbusPathName, QObject *parent = nullptr); ~QNetworkManagerIp4Config(); QStringList domains() const; @@ -489,7 +489,7 @@ class PropertiesDBusInterface : public QDBusAbstractInterface public: PropertiesDBusInterface(const QString &service, const QString &path, const QString &interface, const QDBusConnection &connection, - QObject *parent = 0) + QObject *parent = nullptr) : QDBusAbstractInterface(service, path, interface.toLatin1().data(), connection, parent) {} }; diff --git a/src/plugins/bearer/nla/nla.pro b/src/plugins/bearer/nla/nla.pro index 113d0667d2..76f3279d25 100644 --- a/src/plugins/bearer/nla/nla.pro +++ b/src/plugins/bearer/nla/nla.pro @@ -2,7 +2,7 @@ TARGET = qnlabearer QT = core core-private network network-private -LIBS += -lws2_32 +QMAKE_USE_PRIVATE += ws2_32 HEADERS += qnlaengine.h \ ../platformdefs_win.h \ diff --git a/src/plugins/bearer/nla/qnlaengine.cpp b/src/plugins/bearer/nla/qnlaengine.cpp index 726e1efb92..e1e60389f1 100644 --- a/src/plugins/bearer/nla/qnlaengine.cpp +++ b/src/plugins/bearer/nla/qnlaengine.cpp @@ -75,38 +75,38 @@ QWindowsSockInit2::~QWindowsSockInit2() #ifdef BEARER_MANAGEMENT_DEBUG static void printBlob(NLA_BLOB *blob) { - qDebug() << "==== BEGIN NLA_BLOB ====" << endl + qDebug() << "==== BEGIN NLA_BLOB ====" << Qt::endl - << "type:" << blob->header.type << endl - << "size:" << blob->header.dwSize << endl + << "type:" << blob->header.type << Qt::endl + << "size:" << blob->header.dwSize << Qt::endl << "next offset:" << blob->header.nextOffset; switch (blob->header.type) { case NLA_RAW_DATA: - qDebug() << "Raw Data" << endl + qDebug() << "Raw Data" << Qt::endl << '\t' << blob->data.rawData; break; case NLA_INTERFACE: - qDebug() << "Interface" << endl - << "\ttype:" << blob->data.interfaceData.dwType << endl - << "\tspeed:" << blob->data.interfaceData.dwSpeed << endl + qDebug() << "Interface" << Qt::endl + << "\ttype:" << blob->data.interfaceData.dwType << Qt::endl + << "\tspeed:" << blob->data.interfaceData.dwSpeed << Qt::endl << "\tadapter:" << blob->data.interfaceData.adapterName; break; case NLA_802_1X_LOCATION: - qDebug() << "802.1x Location" << endl + qDebug() << "802.1x Location" << Qt::endl << '\t' << blob->data.locationData.information; break; case NLA_CONNECTIVITY: - qDebug() << "Connectivity" << endl - << "\ttype:" << blob->data.connectivity.type << endl + qDebug() << "Connectivity" << Qt::endl + << "\ttype:" << blob->data.connectivity.type << Qt::endl << "\tinternet:" << blob->data.connectivity.internet; break; case NLA_ICS: - qDebug() << "ICS" << endl - << "\tspeed:" << blob->data.ICS.remote.speed << endl - << "\ttype:" << blob->data.ICS.remote.type << endl - << "\tstate:" << blob->data.ICS.remote.state << endl - << "\tmachine name:" << blob->data.ICS.remote.machineName << endl + qDebug() << "ICS" << Qt::endl + << "\tspeed:" << blob->data.ICS.remote.speed << Qt::endl + << "\ttype:" << blob->data.ICS.remote.type << Qt::endl + << "\tstate:" << blob->data.ICS.remote.state << Qt::endl + << "\tmachine name:" << blob->data.ICS.remote.machineName << Qt::endl << "\tshared adapter name:" << blob->data.ICS.remote.sharedAdapterName; break; default: @@ -119,9 +119,6 @@ static void printBlob(NLA_BLOB *blob) static QNetworkConfiguration::BearerType qGetInterfaceType(const QString &interface) { -#ifdef Q_OS_WINCE - Q_UNUSED(interface) -#else unsigned long oid; DWORD bytesWritten; @@ -177,8 +174,6 @@ static QNetworkConfiguration::BearerType qGetInterfaceType(const QString &interf qDebug() << medium << physicalMedium; #endif -#endif - return QNetworkConfiguration::BearerUnknown; } @@ -307,16 +302,12 @@ void QNlaThread::run() break; } -#ifndef Q_OS_WINCE // Not interested in unrelated IO completion events // although we also don't want to block them while (WaitForSingleObjectEx(changeEvent, WSA_INFINITE, true) != WAIT_IO_COMPLETION && handle) { } -#else - WaitForSingleObject(changeEvent, WSA_INFINITE); -#endif mutex.lock(); if (handle) { diff --git a/src/plugins/bearer/qbearerengine_impl.h b/src/plugins/bearer/qbearerengine_impl.h index 3f8a4d821d..5c003aaaf6 100644 --- a/src/plugins/bearer/qbearerengine_impl.h +++ b/src/plugins/bearer/qbearerengine_impl.h @@ -56,7 +56,7 @@ public: DisconnectionError, }; - QBearerEngineImpl(QObject *parent = 0) : QBearerEngine(parent) {} + QBearerEngineImpl(QObject *parent = nullptr) : QBearerEngine(parent) {} ~QBearerEngineImpl() {} virtual void connectToId(const QString &id) = 0; diff --git a/src/plugins/bearer/qnetworksession_impl.h b/src/plugins/bearer/qnetworksession_impl.h index d9aa6ca8fb..0f8e014900 100644 --- a/src/plugins/bearer/qnetworksession_impl.h +++ b/src/plugins/bearer/qnetworksession_impl.h @@ -66,7 +66,7 @@ class QNetworkSessionPrivateImpl : public QNetworkSessionPrivate public: QNetworkSessionPrivateImpl() - : engine(0), startTime(0), lastError(QNetworkSession::UnknownSessionError), sessionTimeout(-1), currentPolicies(QNetworkSession::NoPolicy), opened(false) + : engine(nullptr), startTime(0), lastError(QNetworkSession::UnknownSessionError), sessionTimeout(-1), currentPolicies(QNetworkSession::NoPolicy), opened(false) {} ~QNetworkSessionPrivateImpl() {} diff --git a/src/plugins/imageformats/jpeg/qjpeghandler.cpp b/src/plugins/imageformats/jpeg/qjpeghandler.cpp index aed2900356..1f1675e490 100644 --- a/src/plugins/imageformats/jpeg/qjpeghandler.cpp +++ b/src/plugins/imageformats/jpeg/qjpeghandler.cpp @@ -40,10 +40,14 @@ #include "qjpeghandler_p.h" #include <qimage.h> +#include <qcolorspace.h> +#include <qcolortransform.h> +#include <qdebug.h> #include <qvariant.h> #include <qvector.h> #include <qbuffer.h> #include <qmath.h> +#include <private/qicc_p.h> #include <private/qsimd_p.h> #include <private/qimage_p.h> // for qt_getImageText @@ -488,6 +492,8 @@ inline my_jpeg_destination_mgr::my_jpeg_destination_mgr(QIODevice *device) free_in_buffer = max_buf; } +static constexpr int maxMarkerSize = 65533; + static inline void set_text(const QImage &image, j_compress_ptr cinfo, const QString &description) { const QMap<QString, QString> text = qt_getImageText(image, description); @@ -496,12 +502,33 @@ static inline void set_text(const QImage &image, j_compress_ptr cinfo, const QSt if (!comment.isEmpty()) comment += ": "; comment += it.value().toUtf8(); - if (comment.length() > 65530) - comment.truncate(65530); + if (comment.length() > maxMarkerSize) + comment.truncate(maxMarkerSize); jpeg_write_marker(cinfo, JPEG_COM, (const JOCTET *)comment.constData(), comment.size()); } } +static inline void write_icc_profile(const QImage &image, j_compress_ptr cinfo) +{ + const QByteArray iccProfile = image.colorSpace().iccProfile(); + if (iccProfile.isEmpty()) + return; + + const QByteArray iccSignature("ICC_PROFILE", 12); + constexpr int maxIccMarkerSize = maxMarkerSize - (12 + 2); + int index = 0; + const int markers = (iccProfile.size() + (maxIccMarkerSize - 1)) / maxIccMarkerSize; + Q_ASSERT(markers < 256); + for (int marker = 1; marker <= markers; ++marker) { + const int len = std::min(iccProfile.size() - index, maxIccMarkerSize); + const QByteArray block = iccSignature + + QByteArray(1, char(marker)) + QByteArray(1, char(markers)) + + iccProfile.mid(index, len); + jpeg_write_marker(cinfo, JPEG_APP0 + 2, reinterpret_cast<const JOCTET *>(block.constData()), block.size()); + index += len; + } +} + static bool write_jpeg_image(const QImage &image, QIODevice *device, volatile int sourceQuality, const QString &description, bool optimize, bool progressive) { bool success = false; @@ -582,6 +609,8 @@ static bool write_jpeg_image(const QImage &image, QIODevice *device, volatile in jpeg_start_compress(&cinfo, TRUE); set_text(image, &cinfo, description); + if (cinfo.in_color_space == JCS_RGB) + write_icc_profile(image, &cinfo); row_pointer[0] = new uchar[cinfo.image_width*cinfo.input_components]; int w = cinfo.image_width; @@ -725,6 +754,7 @@ public: QRect clipRect; QString description; QStringList readTexts; + QByteArray iccProfile; struct jpeg_decompress_struct info; struct my_jpeg_source_mgr * iod_src; @@ -887,6 +917,7 @@ bool QJpegHandlerPrivate::readJpegHeader(QIODevice *device) if (!setjmp(err.setjmp_buffer)) { jpeg_save_markers(&info, JPEG_COM, 0xFFFF); jpeg_save_markers(&info, JPEG_APP0 + 1, 0xFFFF); // Exif uses APP1 marker + jpeg_save_markers(&info, JPEG_APP0 + 2, 0xFFFF); // ICC uses APP2 marker (void) jpeg_read_header(&info, TRUE); @@ -919,6 +950,10 @@ bool QJpegHandlerPrivate::readJpegHeader(QIODevice *device) readTexts.append(value); } else if (marker->marker == JPEG_APP0 + 1) { exifData.append((const char*)marker->data, marker->data_length); + } else if (marker->marker == JPEG_APP0 + 2) { + if (marker->data_length > 128 + 4 + 14 && strcmp((const char *)marker->data, "ICC_PROFILE") == 0) { + iccProfile.append((const char*)marker->data + 14, marker->data_length - 14); + } } } @@ -954,6 +989,9 @@ bool QJpegHandlerPrivate::read(QImage *image) for (int i = 0; i < readTexts.size()-1; i+=2) image->setText(readTexts.at(i), readTexts.at(i+1)); + if (!iccProfile.isEmpty()) + image->setColorSpace(QColorSpace::fromIccProfile(iccProfile)); + state = ReadingEnd; return true; } @@ -962,7 +1000,6 @@ bool QJpegHandlerPrivate::read(QImage *image) } return false; - } Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32_neon(quint32 *dst, const uchar *src, int len); diff --git a/src/plugins/platforminputcontexts/ibus/qibusinputcontextproxy.h b/src/plugins/platforminputcontexts/ibus/qibusinputcontextproxy.h index 47a40ab8c2..396a213aaa 100644 --- a/src/plugins/platforminputcontexts/ibus/qibusinputcontextproxy.h +++ b/src/plugins/platforminputcontexts/ibus/qibusinputcontextproxy.h @@ -31,7 +31,7 @@ public: { return "org.freedesktop.IBus.InputContext"; } public: - QIBusInputContextProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0); + QIBusInputContextProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = nullptr); ~QIBusInputContextProxy(); diff --git a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h index d4daea2eb3..8e7b8df120 100644 --- a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h +++ b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h @@ -59,9 +59,9 @@ class QIBusFilterEventWatcher: public QDBusPendingCallWatcher { public: explicit QIBusFilterEventWatcher(const QDBusPendingCall &call, - QObject *parent = 0, - QWindow *window = 0, - const Qt::KeyboardModifiers modifiers = 0, + QObject *parent = nullptr, + QWindow *window = nullptr, + const Qt::KeyboardModifiers modifiers = nullptr, const QVariantList arguments = QVariantList()) : QDBusPendingCallWatcher(call, parent) , m_window(window) diff --git a/src/plugins/platforminputcontexts/ibus/qibusproxy.h b/src/plugins/platforminputcontexts/ibus/qibusproxy.h index 839e972c34..c9876deebf 100644 --- a/src/plugins/platforminputcontexts/ibus/qibusproxy.h +++ b/src/plugins/platforminputcontexts/ibus/qibusproxy.h @@ -35,7 +35,7 @@ public: { return QStringLiteral("org.freedesktop.DBus.Properties"); } public: - QIBusProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0); + QIBusProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = nullptr); ~QIBusProxy(); diff --git a/src/plugins/platforms/android/android.pro b/src/plugins/platforms/android/android.pro index 78632a9bea..730247cd7f 100644 --- a/src/plugins/platforms/android/android.pro +++ b/src/plugins/platforms/android/android.pro @@ -1,9 +1,5 @@ TARGET = qtforandroid -# STATICPLUGIN needed because there's a Q_IMPORT_PLUGIN in androidjnimain.cpp -# Yes, the plugin imports itself statically -DEFINES += QT_STATICPLUGIN - LIBS += -ljnigraphics -landroid QT += \ @@ -19,7 +15,8 @@ INCLUDEPATH += \ $$PWD \ $$QT_SOURCE_TREE/src/3rdparty/android -SOURCES += $$PWD/androidplatformplugin.cpp \ +SOURCES += $$PWD/main.cpp \ + $$PWD/androidplatformplugin.cpp \ $$PWD/androidcontentfileengine.cpp \ $$PWD/androiddeadlockprotector.cpp \ $$PWD/androidjnimain.cpp \ @@ -92,8 +89,5 @@ qtConfig(vulkan) { } PLUGIN_TYPE = platforms +PLUGIN_CLASS_NAME = QAndroidIntegrationPlugin load(qt_plugin) - -#Non-standard install directory, QTBUG-29859 -DESTDIR = $$DESTDIR/android -target.path = $${target.path}/android diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp index 6ae429b24e..fd2644717e 100644 --- a/src/plugins/platforms/android/androidjnimain.cpp +++ b/src/plugins/platforms/android/androidjnimain.cpp @@ -60,6 +60,7 @@ #include "qandroideventdispatcher.h" #include <android/api-level.h> +#include <QtCore/qresource.h> #include <QtCore/qthread.h> #include <QtCore/private/qjnihelpers_p.h> #include <QtCore/private/qjni_p.h> @@ -68,8 +69,6 @@ #include <qpa/qwindowsysteminterface.h> -Q_IMPORT_PLUGIN(QAndroidPlatformIntegrationPlugin) - QT_BEGIN_NAMESPACE static JavaVM *m_javaVM = nullptr; @@ -77,6 +76,7 @@ static jclass m_applicationClass = nullptr; static jobject m_classLoaderObject = nullptr; static jmethodID m_loadClassMethodID = nullptr; static AAssetManager *m_assetManager = nullptr; +static jobject m_assets = nullptr; static jobject m_resourcesObj = nullptr; static jobject m_activityObject = nullptr; static jmethodID m_createSurfaceMethodID = nullptr; @@ -441,6 +441,11 @@ namespace QtAndroid return block; } + jobject assets() + { + return m_assets; + } + } // namespace QtAndroid static jboolean startQtAndroidPlugin(JNIEnv *env, jobject /*object*/, jstring paramsString, jstring environmentString) @@ -454,9 +459,9 @@ static jboolean startQtAndroidPlugin(JNIEnv *env, jobject /*object*/, jstring pa const QList<QByteArray> envVars = QByteArray(nativeString).split('\t'); env->ReleaseStringUTFChars(environmentString, nativeString); for (const QByteArray &envVar : envVars) { - const QList<QByteArray> envVarPair = envVar.split('='); - if (envVarPair.size() == 2 && ::setenv(envVarPair[0], envVarPair[1], 1) != 0) - qWarning() << "Can't set environment" << envVarPair; + int pos = envVar.indexOf('='); + if (pos != -1 && ::setenv(envVar.left(pos), envVar.mid(pos + 1), 1) != 0) + qWarning() << "Can't set environment" << envVar; } } @@ -485,7 +490,7 @@ static jboolean startQtAndroidPlugin(JNIEnv *env, jobject /*object*/, jstring pa } if (Q_UNLIKELY(!m_main)) { - qCritical() << "dlsym failed:" << dlerror() << endl + qCritical() << "dlsym failed:" << dlerror() << Qt::endl << "Could not find main method"; return false; } @@ -521,6 +526,10 @@ static jboolean startQtApplication(JNIEnv */*env*/, jclass /*clazz*/) vm->AttachCurrentThread(&env, &args); } + // Register resources if they are available + if (QFile{QStringLiteral("assets:/android_rcc_bundle.rcc")}.exists()) + QResource::registerResource(QStringLiteral("assets:/android_rcc_bundle.rcc")); + QVarLengthArray<const char *> params(m_applicationParams.size()); for (int i = 0; i < m_applicationParams.size(); i++) params[i] = static_cast<const char *>(m_applicationParams[i].constData()); @@ -590,6 +599,8 @@ static void terminateQt(JNIEnv *env, jclass /*clazz*/) env->DeleteGlobalRef(m_RGB_565_BitmapConfigValue); if (m_bitmapDrawableClass) env->DeleteGlobalRef(m_bitmapDrawableClass); + if (m_assets) + env->DeleteGlobalRef(m_assets); m_androidPlatformIntegration = nullptr; delete m_androidAssetsFileEngineHandler; m_androidAssetsFileEngineHandler = nullptr; @@ -842,7 +853,8 @@ static int registerNatives(JNIEnv *env) if (object) { FIND_AND_CHECK_CLASS("android/content/ContextWrapper"); GET_AND_CHECK_METHOD(methodID, clazz, "getAssets", "()Landroid/content/res/AssetManager;"); - m_assetManager = AAssetManager_fromJava(env, env->CallObjectMethod(object, methodID)); + m_assets = env->NewGlobalRef(env->CallObjectMethod(object, methodID)); + m_assetManager = AAssetManager_fromJava(env, m_assets); GET_AND_CHECK_METHOD(methodID, clazz, "getResources", "()Landroid/content/res/Resources;"); m_resourcesObj = env->NewGlobalRef(env->CallObjectMethod(object, methodID)); diff --git a/src/plugins/platforms/android/androidjnimain.h b/src/plugins/platforms/android/androidjnimain.h index 08f1d50fe3..17ae30a1be 100644 --- a/src/plugins/platforms/android/androidjnimain.h +++ b/src/plugins/platforms/android/androidjnimain.h @@ -82,6 +82,7 @@ namespace QtAndroid double scaledDensity(); double pixelDensity(); JavaVM *javaVM(); + jobject assets(); AAssetManager *assetManager(); jclass applicationClass(); jobject activity(); diff --git a/src/plugins/platforms/android/androidjnimenu.cpp b/src/plugins/platforms/android/androidjnimenu.cpp index e9359def0f..de2fdaa0e2 100644 --- a/src/plugins/platforms/android/androidjnimenu.cpp +++ b/src/plugins/platforms/android/androidjnimenu.cpp @@ -60,12 +60,12 @@ namespace QtAndroidMenu { static QList<QAndroidPlatformMenu *> pendingContextMenus; static QAndroidPlatformMenu *visibleMenu = 0; - static QMutex visibleMenuMutex(QMutex::Recursive); + static QRecursiveMutex visibleMenuMutex; static QSet<QAndroidPlatformMenuBar *> menuBars; static QAndroidPlatformMenuBar *visibleMenuBar = 0; static QWindow *activeTopLevelWindow = 0; - static QMutex menuBarMutex(QMutex::Recursive); + static QRecursiveMutex menuBarMutex; static jmethodID openContextMenuMethodID = 0; diff --git a/src/plugins/platforms/mirclient/qmirclientplugin.h b/src/plugins/platforms/android/main.cpp index 207d97b5af..c304fc8d69 100644 --- a/src/plugins/platforms/mirclient/qmirclientplugin.h +++ b/src/plugins/platforms/android/main.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 Canonical, Ltd. +** Copyright (C) 2019 BogDan Vatra <bogdan@kde.org> ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the plugins of the Qt Toolkit. @@ -38,19 +38,26 @@ ****************************************************************************/ -#ifndef QMIRCLIENTPLUGIN_H -#define QMIRCLIENTPLUGIN_H - #include <qpa/qplatformintegrationplugin.h> +#include "qandroidplatformintegration.h" + +QT_BEGIN_NAMESPACE -class QMirClientIntegrationPlugin : public QPlatformIntegrationPlugin +class QAndroidIntegrationPlugin : public QPlatformIntegrationPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID QPlatformIntegrationFactoryInterface_iid FILE "mirclient.json") + Q_PLUGIN_METADATA(IID QPlatformIntegrationFactoryInterface_iid FILE "android.json") public: - QPlatformIntegration *create(const QString &system, const QStringList ¶mList, - int &argc, char **argv) override; + QPlatformIntegration *create(const QString& system, const QStringList& paramList) override; }; -#endif // QMIRCLIENTPLUGIN_H +QPlatformIntegration *QAndroidIntegrationPlugin::create(const QString& system, const QStringList& paramList) +{ + if (!system.compare(QLatin1String("android"), Qt::CaseInsensitive)) + return new QAndroidPlatformIntegration(paramList); + + return nullptr; +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/android/qandroidassetsfileenginehandler.cpp b/src/plugins/platforms/android/qandroidassetsfileenginehandler.cpp index e1dcebfa4c..26e72a480f 100644 --- a/src/plugins/platforms/android/qandroidassetsfileenginehandler.cpp +++ b/src/plugins/platforms/android/qandroidassetsfileenginehandler.cpp @@ -39,40 +39,139 @@ #include "qandroidassetsfileenginehandler.h" #include "androidjnimain.h" +#include <optional> #include <QCoreApplication> #include <QVector> +#include <QtCore/private/qjni_p.h> QT_BEGIN_NAMESPACE -typedef QVector<QString> FilesList; +static const QLatin1String assetsPrefix("assets:"); +const static int prefixSize = 7; -struct AndroidAssetDir +static inline QString cleanedAssetPath(QString file) { - AndroidAssetDir(AAssetDir* ad) + if (file.startsWith(assetsPrefix)) + file.remove(0, prefixSize); + file.replace(QLatin1String("//"), QLatin1String("/")); + if (file.startsWith(QLatin1Char('/'))) + file.remove(0, 1); + if (file.endsWith(QLatin1Char('/'))) + file.chop(1); + return file; +} + +static inline QString prefixedPath(QString path) +{ + path = assetsPrefix + QLatin1Char('/') + path; + path.replace(QLatin1String("//"), QLatin1String("/")); + return path; +} + +struct AssetItem { + enum class Type { + File, + Folder + }; + + AssetItem (const QString &rawName) + : name(rawName) + { + if (name.endsWith(QLatin1Char('/'))) { + type = Type::Folder; + name.chop(1); + } + } + Type type = Type::File; + QString name; +}; + +using AssetItemList = QVector<AssetItem>; + +class FolderIterator : public AssetItemList +{ +public: + static QSharedPointer<FolderIterator> fromCache(const QString &path) { - if (ad) { - const char *fileName; - while ((fileName = AAssetDir_getNextFileName(ad))) - m_items.push_back(QString::fromUtf8(fileName)); - AAssetDir_close(ad); + QMutexLocker lock(&m_assetsCacheMutex); + QSharedPointer<FolderIterator> *folder = m_assetsCache.object(path); + if (!folder) { + folder = new QSharedPointer<FolderIterator>{new FolderIterator{path}}; + if (!m_assetsCache.insert(path, folder)) { + QSharedPointer<FolderIterator> res = *folder; + delete folder; + return res; + } } + return *folder; + } + + FolderIterator(const QString &path) + : m_path(path) + { + QJNIObjectPrivate files = QJNIObjectPrivate::callStaticObjectMethod(QtAndroid::applicationClass(), + "listAssetContent", + "(Landroid/content/res/AssetManager;Ljava/lang/String;)[Ljava/lang/String;", + QtAndroid::assets(), QJNIObjectPrivate::fromString(path).object()); + if (files.isValid()) { + QJNIEnvironmentPrivate env; + jobjectArray jFiles = static_cast<jobjectArray>(files.object()); + const jint nFiles = env->GetArrayLength(jFiles); + for (int i = 0; i < nFiles; ++i) + push_back({QJNIObjectPrivate(env->GetObjectArrayElement(jFiles, i)).toString()}); + } + m_path = assetsPrefix + QLatin1Char('/') + m_path + QLatin1Char('/'); + m_path.replace(QLatin1String("//"), QLatin1String("/")); + } + + QString currentFileName() const + { + if (m_index < 0 || m_index >= size()) + return {}; + return at(m_index).name; + } + QString currentFilePath() const + { + if (m_index < 0 || m_index >= size()) + return {}; + return m_path + at(m_index).name; + } + + bool hasNext() const + { + return !empty() && m_index + 1 < size(); + } + + std::optional<std::pair<QString, AssetItem>> next() + { + if (!hasNext()) + return {}; + ++m_index; + return std::pair<QString, AssetItem>(currentFileName(), at(m_index)); } - FilesList m_items; + +private: + int m_index = -1; + QString m_path; + static QCache<QString, QSharedPointer<FolderIterator>> m_assetsCache; + static QMutex m_assetsCacheMutex; }; +QCache<QString, QSharedPointer<FolderIterator>> FolderIterator::m_assetsCache(std::max(50, qEnvironmentVariableIntValue("QT_ANDROID_MAX_ASSETS_CACHE_SIZE"))); +QMutex FolderIterator::m_assetsCacheMutex; + class AndroidAbstractFileEngineIterator: public QAbstractFileEngineIterator { public: AndroidAbstractFileEngineIterator(QDir::Filters filters, const QStringList &nameFilters, - QSharedPointer<AndroidAssetDir> asset, const QString &path) : QAbstractFileEngineIterator(filters, nameFilters) { - m_items = asset->m_items; - m_index = -1; - m_path = path; + m_stack.push_back(FolderIterator::fromCache(cleanedAssetPath(path))); + if (m_stack.last()->empty()) + m_stack.pop_back(); } QFileInfo currentFileInfo() const override @@ -82,54 +181,59 @@ public: QString currentFileName() const override { - if (m_index < 0 || m_index >= m_items.size()) - return QString(); - QString fileName = m_items[m_index]; - if (fileName.endsWith(QLatin1Char('/'))) - fileName.chop(1); - return fileName; + if (!m_currentIterator) + return {}; + return m_currentIterator->currentFileName(); } virtual QString currentFilePath() const { - return m_path + currentFileName(); + if (!m_currentIterator) + return {}; + return m_currentIterator->currentFilePath(); } bool hasNext() const override { - return m_items.size() && (m_index < m_items.size() - 1); + if (m_stack.empty()) + return false; + if (!m_stack.last()->hasNext()) { + m_stack.pop_back(); + return hasNext(); + } + return true; } QString next() override { - if (!hasNext()) - return QString(); - m_index++; - return currentFileName(); + if (m_stack.empty()) { + m_currentIterator.reset(); + return {}; + } + m_currentIterator = m_stack.last(); + auto res = m_currentIterator->next(); + if (!res) + return {}; + if (res->second.type == AssetItem::Type::Folder) { + m_stack.push_back(FolderIterator::fromCache(cleanedAssetPath(currentFilePath()))); + if (m_stack.last()->empty()) + m_stack.pop_back(); + } + return res->first; } private: - QString m_path; - FilesList m_items; - int m_index; + mutable QSharedPointer<FolderIterator> m_currentIterator; + mutable QVector<QSharedPointer<FolderIterator>> m_stack; }; class AndroidAbstractFileEngine: public QAbstractFileEngine { public: - explicit AndroidAbstractFileEngine(AAsset *asset, const QString &fileName) - { - m_assetFile = asset; - m_fileName = fileName; - } - - explicit AndroidAbstractFileEngine(QSharedPointer<AndroidAssetDir> asset, const QString &fileName) + explicit AndroidAbstractFileEngine(AAssetManager *assetManager, const QString &fileName) + : m_assetManager(assetManager) { - m_assetFile = 0; - m_assetDir = asset; - m_fileName = fileName; - if (!m_fileName.endsWith(QLatin1Char('/'))) - m_fileName += QLatin1Char('/'); + setFileName(fileName); } ~AndroidAbstractFileEngine() @@ -139,7 +243,11 @@ public: bool open(QIODevice::OpenMode openMode) override { - return m_assetFile != 0 && (openMode & QIODevice::WriteOnly) == 0; + if (m_isFolder || (openMode & QIODevice::WriteOnly)) + return false; + close(); + m_assetFile = AAssetManager_open(m_assetManager, m_fileName.toUtf8(), AASSET_MODE_BUFFER); + return m_assetFile; } bool close() override @@ -200,7 +308,7 @@ public: FileFlags flags(ReadOwnerPerm|ReadUserPerm|ReadGroupPerm|ReadOtherPerm|ExistsFlag); if (m_assetFile) flags |= FileType; - if (!m_assetDir.isNull()) + else if (m_isFolder) flags |= DirectoryType; return type & flags; @@ -213,19 +321,19 @@ public: case DefaultName: case AbsoluteName: case CanonicalName: - return m_fileName; + return prefixedPath(m_fileName); case BaseName: if ((pos = m_fileName.lastIndexOf(QChar(QLatin1Char('/')))) != -1) - return m_fileName.mid(pos); + return prefixedPath(m_fileName.mid(pos)); else - return m_fileName; + return prefixedPath(m_fileName); case PathName: case AbsolutePathName: case CanonicalPathName: if ((pos = m_fileName.lastIndexOf(QChar(QLatin1Char('/')))) != -1) - return m_fileName.left(pos); + return prefixedPath(m_fileName.left(pos)); else - return m_fileName; + return prefixedPath(m_fileName); default: return QString(); } @@ -233,164 +341,46 @@ public: void setFileName(const QString &file) override { - if (file == m_fileName) - return; - - m_fileName = file; - if (!m_fileName.endsWith(QLatin1Char('/'))) - m_fileName += QLatin1Char('/'); - close(); + m_fileName = cleanedAssetPath(file); + m_isFolder = !open(QIODevice::ReadOnly) && !FolderIterator::fromCache(m_fileName)->empty(); } Iterator *beginEntryList(QDir::Filters filters, const QStringList &filterNames) override { - if (!m_assetDir.isNull()) - return new AndroidAbstractFileEngineIterator(filters, filterNames, m_assetDir, m_fileName); - return 0; + if (m_isFolder) + return new AndroidAbstractFileEngineIterator(filters, filterNames, m_fileName); + return nullptr; } private: - AAsset *m_assetFile; - QSharedPointer<AndroidAssetDir> m_assetDir; + AAsset *m_assetFile = nullptr; + AAssetManager *m_assetManager; QString m_fileName; + bool m_isFolder; }; AndroidAssetsFileEngineHandler::AndroidAssetsFileEngineHandler() - : m_assetsCache(std::max(5, qEnvironmentVariableIntValue("QT_ANDROID_MAX_ASSETS_CACHE_SIZE"))) - , m_hasPrepopulatedCache(false) - , m_hasTriedPrepopulatingCache(false) { m_assetManager = QtAndroid::assetManager(); } -AndroidAssetsFileEngineHandler::~AndroidAssetsFileEngineHandler() -{ -} - -void AndroidAssetsFileEngineHandler::prepopulateCache() const -{ - Q_ASSERT(!m_hasTriedPrepopulatingCache); - m_hasTriedPrepopulatingCache = true; - - Q_ASSERT(m_assetsCache.isEmpty()); - - // Failsafe: Don't read cache files that are larger than 1MB - static qint64 maxPrepopulatedCacheSize = qMax(1024LL * 1024LL, - qgetenv("QT_ANDROID_MAX_PREPOPULATED_ASSETS_CACHE_SIZE").toLongLong()); - - const char *fileName = "--Added-by-androiddeployqt--/qt_cache_pregenerated_file_list"; - AAsset *asset = AAssetManager_open(m_assetManager, fileName, AASSET_MODE_BUFFER); - if (asset) { - m_hasPrepopulatedCache = true; - AndroidAbstractFileEngine fileEngine(asset, QString::fromLatin1(fileName)); - if (fileEngine.open(QIODevice::ReadOnly)) { - qint64 size = fileEngine.size(); - - if (size <= maxPrepopulatedCacheSize) { - QByteArray bytes(size, Qt::Uninitialized); - qint64 read = fileEngine.read(bytes.data(), size); - if (read != size) { - qWarning("Failed to read prepopulated cache"); - return; - } - - QDataStream stream(&bytes, QIODevice::ReadOnly); - stream.setVersion(QDataStream::Qt_5_3); - if (stream.status() != QDataStream::Ok) { - qWarning("Failed to read prepopulated cache"); - return; - } - - while (!stream.atEnd()) { - QString directoryName; - stream >> directoryName; - - int fileCount; - stream >> fileCount; - - QVector<QString> fileList; - fileList.reserve(fileCount); - while (fileCount--) { - QString fileName; - stream >> fileName; - fileList.append(fileName); - } - - QSharedPointer<AndroidAssetDir> *aad = new QSharedPointer<AndroidAssetDir>(new AndroidAssetDir(0)); - (*aad)->m_items = fileList; - - // Cost = 0, because we should always cache everything if there's a prepopulated cache - QByteArray key = directoryName != QLatin1String("/") - ? QByteArray("assets:/") + directoryName.toUtf8() - : QByteArray("assets:"); - - bool ok = m_assetsCache.insert(key, aad, 0); - if (!ok) - qWarning("Failed to insert in cache: %s", qPrintable(directoryName)); - } - } else { - qWarning("Prepopulated cache is too large to read.\n" - "Use environment variable QT_ANDROID_MAX_PREPOPULATED_ASSETS_CACHE_SIZE to adjust size."); - } - } - } -} - QAbstractFileEngine * AndroidAssetsFileEngineHandler::create(const QString &fileName) const { if (fileName.isEmpty()) - return 0; + return nullptr; - static QLatin1String assetsPrefix("assets:"); if (!fileName.startsWith(assetsPrefix)) - return 0; - - static int prefixSize = assetsPrefix.size() + 1; - - QByteArray path; - if (!fileName.endsWith(QLatin1Char('/'))) { - path = fileName.toUtf8(); - if (path.size() > prefixSize) { - AAsset *asset = AAssetManager_open(m_assetManager, - path.constData() + prefixSize, - AASSET_MODE_BUFFER); - if (asset) - return new AndroidAbstractFileEngine(asset, fileName); - } - } - - if (!path.size()) - path = fileName.left(fileName.length() - 1).toUtf8(); - - - m_assetsCacheMutext.lock(); - if (!m_hasTriedPrepopulatingCache) - prepopulateCache(); - - QSharedPointer<AndroidAssetDir> *aad = m_assetsCache.object(path); - m_assetsCacheMutext.unlock(); - if (!aad) { - if (!m_hasPrepopulatedCache && path.size() > prefixSize) { - AAssetDir *assetDir = AAssetManager_openDir(m_assetManager, path.constData() + prefixSize); - if (assetDir) { - if (AAssetDir_getNextFileName(assetDir)) { - AAssetDir_rewind(assetDir); - aad = new QSharedPointer<AndroidAssetDir>(new AndroidAssetDir(assetDir)); - m_assetsCacheMutext.lock(); - m_assetsCache.insert(path, aad); - m_assetsCacheMutext.unlock(); - return new AndroidAbstractFileEngine(*aad, fileName); - } else { - AAssetDir_close(assetDir); - } - } - } - } else { - return new AndroidAbstractFileEngine(*aad, fileName); - } - return 0; + return nullptr; + + QString path = fileName.mid(prefixSize); + path.replace(QLatin1String("//"), QLatin1String("/")); + if (path.startsWith(QLatin1Char('/'))) + path.remove(0, 1); + if (path.endsWith(QLatin1Char('/'))) + path.chop(1); + return new AndroidAbstractFileEngine(m_assetManager, path); } QT_END_NAMESPACE diff --git a/src/plugins/platforms/android/qandroidassetsfileenginehandler.h b/src/plugins/platforms/android/qandroidassetsfileenginehandler.h index f99dc9a11a..51cc5b07a8 100644 --- a/src/plugins/platforms/android/qandroidassetsfileenginehandler.h +++ b/src/plugins/platforms/android/qandroidassetsfileenginehandler.h @@ -49,22 +49,14 @@ QT_BEGIN_NAMESPACE -struct AndroidAssetDir; class AndroidAssetsFileEngineHandler: public QAbstractFileEngineHandler { public: AndroidAssetsFileEngineHandler(); - virtual ~AndroidAssetsFileEngineHandler(); QAbstractFileEngine *create(const QString &fileName) const override; private: - void prepopulateCache() const; - AAssetManager *m_assetManager; - mutable QCache<QByteArray, QSharedPointer<AndroidAssetDir>> m_assetsCache; - mutable QMutex m_assetsCacheMutext; - mutable bool m_hasPrepopulatedCache; - mutable bool m_hasTriedPrepopulatingCache; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/android/qandroideventdispatcher.cpp b/src/plugins/platforms/android/qandroideventdispatcher.cpp index e12551283f..3a1fb7a6de 100644 --- a/src/plugins/platforms/android/qandroideventdispatcher.cpp +++ b/src/plugins/platforms/android/qandroideventdispatcher.cpp @@ -78,14 +78,14 @@ void QAndroidEventDispatcher::stop() void QAndroidEventDispatcher::goingToStop(bool stop) { - m_goingToStop.store(stop ? 1 : 0); + m_goingToStop.storeRelaxed(stop ? 1 : 0); if (!stop) wakeUp(); } bool QAndroidEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) { - if (m_goingToStop.load()) + if (m_goingToStop.loadRelaxed()) flags |= QEventLoop::ExcludeSocketNotifiers | QEventLoop::X11ExcludeTimers; { diff --git a/src/plugins/platforms/android/qandroideventdispatcher.h b/src/plugins/platforms/android/qandroideventdispatcher.h index e6f903bced..4fdd7af7a5 100644 --- a/src/plugins/platforms/android/qandroideventdispatcher.h +++ b/src/plugins/platforms/android/qandroideventdispatcher.h @@ -68,7 +68,7 @@ class QAndroidEventDispatcherStopper { public: static QAndroidEventDispatcherStopper *instance(); - static bool stopped() {return !instance()->m_started.load(); } + static bool stopped() {return !instance()->m_started.loadRelaxed(); } void startAll(); void stopAll(); void addEventDispatcher(QAndroidEventDispatcher *dispatcher); diff --git a/src/plugins/platforms/android/qandroidplatformscreen.cpp b/src/plugins/platforms/android/qandroidplatformscreen.cpp index 7dc8bb8080..80757c2135 100644 --- a/src/plugins/platforms/android/qandroidplatformscreen.cpp +++ b/src/plugins/platforms/android/qandroidplatformscreen.cpp @@ -401,15 +401,17 @@ void QAndroidPlatformScreen::doRedraw() m_dirtyRect = QRect(); } +static const int androidLogicalDpi = 72; + QDpi QAndroidPlatformScreen::logicalDpi() const { - qreal lDpi = QtAndroid::scaledDensity() * 72; + qreal lDpi = QtAndroid::scaledDensity() * androidLogicalDpi; return QDpi(lDpi, lDpi); } -qreal QAndroidPlatformScreen::pixelDensity() const +QDpi QAndroidPlatformScreen::logicalBaseDpi() const { - return QtAndroid::pixelDensity(); + return QDpi(androidLogicalDpi, androidLogicalDpi); } Qt::ScreenOrientation QAndroidPlatformScreen::orientation() const diff --git a/src/plugins/platforms/android/qandroidplatformscreen.h b/src/plugins/platforms/android/qandroidplatformscreen.h index f15aeae3fd..5dc158e351 100644 --- a/src/plugins/platforms/android/qandroidplatformscreen.h +++ b/src/plugins/platforms/android/qandroidplatformscreen.h @@ -103,7 +103,7 @@ protected: private: QDpi logicalDpi() const override; - qreal pixelDensity() const override; + QDpi logicalBaseDpi() const override; Qt::ScreenOrientation orientation() const override; Qt::ScreenOrientation nativeOrientation() const override; void surfaceChanged(JNIEnv *env, jobject surface, int w, int h) override; diff --git a/src/plugins/platforms/android/qandroidplatformwindow.cpp b/src/plugins/platforms/android/qandroidplatformwindow.cpp index c095f51fa3..4f691ce112 100644 --- a/src/plugins/platforms/android/qandroidplatformwindow.cpp +++ b/src/plugins/platforms/android/qandroidplatformwindow.cpp @@ -49,13 +49,14 @@ QT_BEGIN_NAMESPACE +static QBasicAtomicInt winIdGenerator = Q_BASIC_ATOMIC_INITIALIZER(0); + QAndroidPlatformWindow::QAndroidPlatformWindow(QWindow *window) : QPlatformWindow(window) { m_windowFlags = Qt::Widget; m_windowState = Qt::WindowNoState; - static QAtomicInt winIdGenerator(1); - m_windowId = winIdGenerator.fetchAndAddRelaxed(1); + m_windowId = winIdGenerator.fetchAndAddRelaxed(1) + 1; setWindowState(window->windowStates()); } diff --git a/src/plugins/platforms/android/qandroidplatformwindow.h b/src/plugins/platforms/android/qandroidplatformwindow.h index f2e51bd3df..d8eb6b7b7f 100644 --- a/src/plugins/platforms/android/qandroidplatformwindow.h +++ b/src/plugins/platforms/android/qandroidplatformwindow.h @@ -65,6 +65,9 @@ public: void setParent(const QPlatformWindow *window) override; WId winId() const override { return m_windowId; } + bool setMouseGrabEnabled(bool grab) override { Q_UNUSED(grab); return false; } + bool setKeyboardGrabEnabled(bool grab) override { Q_UNUSED(grab); return false; } + QAndroidPlatformScreen *platformScreen() const; void propagateSizeHints() override; diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibility.h b/src/plugins/platforms/cocoa/qcocoaaccessibility.h index 457c158ddc..539d876094 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibility.h +++ b/src/plugins/platforms/cocoa/qcocoaaccessibility.h @@ -44,9 +44,9 @@ #include <QtGui> #include <qpa/qplatformaccessibility.h> -#ifndef QT_NO_ACCESSIBILITY +#include "qcocoaaccessibilityelement.h" -@class QT_MANGLE_NAMESPACE(QMacAccessibilityElement); +#ifndef QT_NO_ACCESSIBILITY QT_BEGIN_NAMESPACE @@ -84,7 +84,7 @@ namespace QCocoaAccessible { NSString *macRole(QAccessibleInterface *interface); NSString *macSubrole(QAccessibleInterface *interface); bool shouldBeIgnored(QAccessibleInterface *interface); -NSArray<QT_MANGLE_NAMESPACE(QMacAccessibilityElement) *> *unignoredChildren(QAccessibleInterface *interface); +NSArray<QMacAccessibilityElement *> *unignoredChildren(QAccessibleInterface *interface); NSString *getTranslatedAction(const QString &qtAction); QString translateAction(NSString *nsAction, QAccessibleInterface *interface); bool hasValueAttribute(QAccessibleInterface *interface); diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm index 368cf56c80..db4ec251ae 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm +++ b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm @@ -177,7 +177,7 @@ NSString *macRole(QAccessibleInterface *interface) if (roleMap.isEmpty()) populateRoleMap(); - // MAC_ACCESSIBILTY_DEBUG() << "role for" << interface.object() << "interface role" << hex << qtRole; + // MAC_ACCESSIBILTY_DEBUG() << "role for" << interface.object() << "interface role" << Qt::hex << qtRole; if (roleMap.contains(qtRole)) { // MAC_ACCESSIBILTY_DEBUG() << "return" << roleMap[qtRole]; diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.h b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.h index 914aaa2b1b..141ce6bf1a 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.h +++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.h @@ -50,9 +50,7 @@ #import <qaccessible.h> -@class QT_MANGLE_NAMESPACE(QMacAccessibilityElement); - -@interface QT_MANGLE_NAMESPACE(QMacAccessibilityElement) : NSObject +@interface QT_MANGLE_NAMESPACE(QMacAccessibilityElement) : NSObject <NSAccessibilityElement> - (instancetype)initWithId:(QAccessible::Id)anId; + (instancetype)elementWithId:(QAccessible::Id)anId; diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm index f0ef70e3a3..3560c9d9b5 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm +++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm @@ -174,6 +174,17 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of // accessibility protocol // +- (BOOL)isAccessibilityFocused +{ + QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); + if (!iface || !iface->isValid()) { + return false; + } + // Just check if the app thinks we're focused. + id focusedElement = NSApp.accessibilityApplicationFocusedUIElement; + return [focusedElement isEqual:self]; +} + // attributes + (id) lineNumberForIndex: (int)index forText:(const QString &)text @@ -187,54 +198,58 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of return YES; } -- (NSArray<NSString *> *)accessibilityAttributeNames { - static NSArray<NSString *> *defaultAttributes = [@[ - NSAccessibilityRoleAttribute, - NSAccessibilityRoleDescriptionAttribute, - NSAccessibilitySubroleAttribute, - NSAccessibilityChildrenAttribute, - NSAccessibilityFocusedAttribute, - NSAccessibilityParentAttribute, - NSAccessibilityWindowAttribute, - NSAccessibilityTopLevelUIElementAttribute, - NSAccessibilityPositionAttribute, - NSAccessibilitySizeAttribute, - NSAccessibilityTitleAttribute, - NSAccessibilityDescriptionAttribute, - NSAccessibilityEnabledAttribute - ] retain]; +- (NSString *) accessibilityRole { + QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); + if (!iface || !iface->isValid()) + return NSAccessibilityUnknownRole; + return QCocoaAccessible::macRole(iface); +} +- (NSString *) accessibilitySubRole { QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); if (!iface || !iface->isValid()) - return defaultAttributes; + return NSAccessibilityUnknownRole; + return QCocoaAccessible::macSubrole(iface); +} - NSMutableArray<NSString *> *attributes = [[NSMutableArray<NSString *> alloc] initWithCapacity:defaultAttributes.count]; - [attributes addObjectsFromArray:defaultAttributes]; +- (NSString *) accessibilityRoleDescription { + QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); + if (!iface || !iface->isValid()) + return NSAccessibilityUnknownRole; + return NSAccessibilityRoleDescription(self.accessibilityRole, self.accessibilitySubRole); +} - if (QCocoaAccessible::hasValueAttribute(iface)) { - [attributes addObject:NSAccessibilityValueAttribute]; - } +- (NSArray *) accessibilityChildren { + QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); + if (!iface || !iface->isValid()) + return nil; + return QCocoaAccessible::unignoredChildren(iface); +} - if (iface->textInterface()) { - [attributes addObjectsFromArray:@[ - NSAccessibilityNumberOfCharactersAttribute, - NSAccessibilitySelectedTextAttribute, - NSAccessibilitySelectedTextRangeAttribute, - NSAccessibilityVisibleCharacterRangeAttribute, - NSAccessibilityInsertionPointLineNumberAttribute - ]]; - -// TODO: multi-selection: NSAccessibilitySelectedTextRangesAttribute, - } +- (id) accessibilityWindow { + // We're in the same window as our parent. + return [self.accessibilityParent accessibilityWindow]; +} - if (iface->valueInterface()) { - [attributes addObjectsFromArray:@[ - NSAccessibilityMinValueAttribute, - NSAccessibilityMaxValueAttribute - ]]; - } +- (id) accessibilityTopLevelUIElementAttribute { + // We're in the same top level element as our parent. + return [self.accessibilityParent accessibilityTopLevelUIElementAttribute]; +} - return [attributes autorelease]; +- (NSString *) accessibilityTitle { + QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); + if (!iface || !iface->isValid()) + return nil; + if (iface->role() == QAccessible::StaticText) + return nil; + return iface->text(QAccessible::Name).toNSString(); +} + +- (BOOL) accessibilityEnabledAttribute { + QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); + if (!iface || !iface->isValid()) + return false; + return !iface->state().disabled; } - (id)accessibilityParent { @@ -271,112 +286,117 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of return QCocoaScreen::mapToNative(iface->rect()); } -- (id) minValueAttribute:(QAccessibleInterface*)iface { +- (NSString*)accessibilityLabel { + QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); + if (!iface || !iface->isValid()) { + qWarning() << "Called accessibilityLabel on invalid object: " << axid; + return nil; + } + return iface->text(QAccessible::Description).toNSString(); +} + +- (void)setAccessibilityLabel:(NSString*)label{ + QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); + if (!iface || !iface->isValid()) + return; + iface->setText(QAccessible::Description, QString::fromNSString(label)); +} + +- (id) accessibilityMinValue:(QAccessibleInterface*)iface { if (QAccessibleValueInterface *val = iface->valueInterface()) return @(val->minimumValue().toDouble()); return nil; } -- (id) maxValueAttribute:(QAccessibleInterface*)iface { +- (id) accessibilityMaxValue:(QAccessibleInterface*)iface { if (QAccessibleValueInterface *val = iface->valueInterface()) return @(val->maximumValue().toDouble()); return nil; } -- (id)accessibilityAttributeValue:(NSString *)attribute { +- (id) accessibilityValue { QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); - if (!iface || !iface->isValid()) { - qWarning() << "Called attribute on invalid object: " << axid; + if (!iface || !iface->isValid()) return nil; - } - if ([attribute isEqualToString:NSAccessibilityRoleAttribute]) { - return QCocoaAccessible::macRole(iface); - } else if ([attribute isEqualToString:NSAccessibilitySubroleAttribute]) { - return QCocoaAccessible::macSubrole(iface); - } else if ([attribute isEqualToString:NSAccessibilityRoleDescriptionAttribute]) { - return NSAccessibilityRoleDescription(QCocoaAccessible::macRole(iface), - [self accessibilityAttributeValue:NSAccessibilitySubroleAttribute]); - } else if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) { - return QCocoaAccessible::unignoredChildren(iface); - } else if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) { - // Just check if the app thinks we're focused. - id focusedElement = [NSApp accessibilityAttributeValue:NSAccessibilityFocusedUIElementAttribute]; - return @([focusedElement isEqual:self]); - } else if ([attribute isEqualToString:NSAccessibilityParentAttribute]) { - return self.accessibilityParent; - } else if ([attribute isEqualToString:NSAccessibilityWindowAttribute]) { - // We're in the same window as our parent. - return [[self accessibilityParent] accessibilityAttributeValue:NSAccessibilityWindowAttribute]; - } else if ([attribute isEqualToString:NSAccessibilityTopLevelUIElementAttribute]) { - // We're in the same top level element as our parent. - return [[self accessibilityParent] accessibilityAttributeValue:NSAccessibilityTopLevelUIElementAttribute]; - } else if ([attribute isEqualToString:NSAccessibilityPositionAttribute]) { - // The position in points of the element's lower-left corner in screen-relative coordinates - QPointF qtPosition = QRectF(iface->rect()).bottomLeft(); - return [NSValue valueWithPoint:QCocoaScreen::mapToNative(qtPosition)]; - } else if ([attribute isEqualToString:NSAccessibilitySizeAttribute]) { - QSize qtSize = iface->rect().size(); - return [NSValue valueWithSize: NSMakeSize(qtSize.width(), qtSize.height())]; - } else if ([attribute isEqualToString:NSAccessibilityTitleAttribute]) { - if (iface->role() == QAccessible::StaticText) - return nil; - return iface->text(QAccessible::Name).toNSString(); - } else if ([attribute isEqualToString:NSAccessibilityDescriptionAttribute]) { - return iface->text(QAccessible::Description).toNSString(); - } else if ([attribute isEqualToString:NSAccessibilityEnabledAttribute]) { - return @(!iface->state().disabled); - } else if ([attribute isEqualToString:NSAccessibilityValueAttribute]) { - // VoiceOver asks for the value attribute for all elements. Return nil - // if we don't want the element to have a value attribute. - if (!QCocoaAccessible::hasValueAttribute(iface)) - return nil; + // VoiceOver asks for the value attribute for all elements. Return nil + // if we don't want the element to have a value attribute. + if (!QCocoaAccessible::hasValueAttribute(iface)) + return nil; + + return QCocoaAccessible::getValueAttribute(iface); +} - return QCocoaAccessible::getValueAttribute(iface); +- (NSInteger) accessibilityNumberOfCharacters { + QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); + if (!iface || !iface->isValid()) + return 0; + if (QAccessibleTextInterface *text = iface->textInterface()) + return text->characterCount(); + return 0; +} - } else if ([attribute isEqualToString:NSAccessibilityNumberOfCharactersAttribute]) { - if (QAccessibleTextInterface *text = iface->textInterface()) - return @(text->characterCount()); +- (NSString *) accessibilitySelectedText { + QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); + if (!iface || !iface->isValid()) return nil; - } else if ([attribute isEqualToString:NSAccessibilitySelectedTextAttribute]) { - if (QAccessibleTextInterface *text = iface->textInterface()) { - int start = 0; - int end = 0; + if (QAccessibleTextInterface *text = iface->textInterface()) { + int start = 0; + int end = 0; + text->selection(0, &start, &end); + return text->text(start, end).toNSString(); + } + return nil; +} + +- (NSRange) accessibilitySelectedTextRange { + QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); + if (!iface || !iface->isValid()) + return NSRange(); + if (QAccessibleTextInterface *text = iface->textInterface()) { + int start = 0; + int end = 0; + if (text->selectionCount() > 0) { text->selection(0, &start, &end); - return text->text(start, end).toNSString(); - } - return nil; - } else if ([attribute isEqualToString:NSAccessibilitySelectedTextRangeAttribute]) { - if (QAccessibleTextInterface *text = iface->textInterface()) { - int start = 0; - int end = 0; - if (text->selectionCount() > 0) { - text->selection(0, &start, &end); - } else { - start = text->cursorPosition(); - end = start; - } - return [NSValue valueWithRange:NSMakeRange(quint32(start), quint32(end - start))]; - } - return [NSValue valueWithRange: NSMakeRange(0, 0)]; - } else if ([attribute isEqualToString:NSAccessibilityVisibleCharacterRangeAttribute]) { - // FIXME This is not correct and may impact performance for big texts - if (QAccessibleTextInterface *text = iface->textInterface()) - return [NSValue valueWithRange: NSMakeRange(0, text->characterCount())]; - return [NSValue valueWithRange: NSMakeRange(0, iface->text(QAccessible::Name).length())]; - } else if ([attribute isEqualToString:NSAccessibilityInsertionPointLineNumberAttribute]) { - if (QAccessibleTextInterface *text = iface->textInterface()) { - int position = text->cursorPosition(); - return [self accessibilityAttributeValue:NSAccessibilityLineForIndexParameterizedAttribute forParameter:@(position)]; + } else { + start = text->cursorPosition(); + end = start; } - return nil; - } else if ([attribute isEqualToString:NSAccessibilityMinValueAttribute]) { - return [self minValueAttribute:iface]; - } else if ([attribute isEqualToString:NSAccessibilityMaxValueAttribute]) { - return [self maxValueAttribute:iface]; + return NSMakeRange(quint32(start), quint32(end - start)); } + return NSMakeRange(0, 0); +} - return nil; +- (NSInteger)accessibilityLineForIndex:(NSInteger)index { + QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); + if (!iface || !iface->isValid()) + return 0; + if (QAccessibleTextInterface *text = iface->textInterface()) { + QString textToPos = text->text(0, index); + return textToPos.count('\n'); + } + return 0; +} + +- (NSRange)accessibilityVisibleCharacterRange { + QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); + if (!iface || !iface->isValid()) + return NSRange(); + // FIXME This is not correct and may impact performance for big texts + if (QAccessibleTextInterface *text = iface->textInterface()) + return NSMakeRange(0, static_cast<uint>(text->characterCount())); + return NSMakeRange(0, static_cast<uint>(iface->text(QAccessible::Name).length())); +} + +- (NSInteger) accessibilityInsertionPointLineNumber { + QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); + if (!iface || !iface->isValid()) + return 0; + if (QAccessibleTextInterface *text = iface->textInterface()) { + int position = text->cursorPosition(); + return [self accessibilityLineForIndex:position]; + } + return 0; } - (NSArray *)accessibilityParameterizedAttributeNames { diff --git a/src/plugins/platforms/cocoa/qcocoaapplication.mm b/src/plugins/platforms/cocoa/qcocoaapplication.mm index 340191622a..c6029bcf03 100644 --- a/src/plugins/platforms/cocoa/qcocoaapplication.mm +++ b/src/plugins/platforms/cocoa/qcocoaapplication.mm @@ -144,7 +144,7 @@ static void qt_maybeSendKeyEquivalentUpEvent(NSEvent *event) } } -@implementation QT_MANGLE_NAMESPACE(QNSApplication) +@implementation QNSApplication - (void)QT_MANGLE_NAMESPACE(qt_sendEvent_original):(NSEvent *)event { @@ -188,7 +188,7 @@ void qt_redirectNSApplicationSendEvent() // can be unloaded. return; - if ([NSApp isMemberOfClass:[QT_MANGLE_NAMESPACE(QNSApplication) class]]) { + if ([NSApp isMemberOfClass:[QNSApplication class]]) { // No need to change implementation since Qt // already controls a subclass of NSApplication return; @@ -201,7 +201,7 @@ void qt_redirectNSApplicationSendEvent() qt_cocoa_change_implementation( [NSApplication class], @selector(sendEvent:), - [QT_MANGLE_NAMESPACE(QNSApplication) class], + [QNSApplication class], @selector(QT_MANGLE_NAMESPACE(qt_sendEvent_replacement):), @selector(QT_MANGLE_NAMESPACE(qt_sendEvent_original):)); } diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h index 0816730c54..8ec9d6fbe0 100644 --- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h +++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h @@ -89,8 +89,7 @@ #include <qglobal.h> #include <private/qcore_mac_p.h> - -Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QCocoaNSMenuItem)); +#include "qcocoansmenu.h" @interface QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) : NSObject <NSApplicationDelegate> @property (nonatomic, retain) NSMenu *dockMenu; @@ -100,8 +99,9 @@ Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QCocoaNSMenuItem)); - (bool)inLaunch; @end -@interface QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) (MenuAPI) -- (void)qt_itemFired:(QT_MANGLE_NAMESPACE(QCocoaNSMenuItem) *)item; +QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaApplicationDelegate); + +@interface QCocoaApplicationDelegate (MenuAPI) +- (void)qt_itemFired:(QCocoaNSMenuItem *)item; @end -QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaApplicationDelegate); diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm index 2cf6672da9..9b0a6b1b86 100644 --- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm +++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm @@ -88,10 +88,13 @@ #include <qpa/qwindowsysteminterface.h> #include <qwindowdefs.h> +QT_BEGIN_NAMESPACE +Q_LOGGING_CATEGORY(lcQpaApplication, "qt.qpa.application"); +QT_END_NAMESPACE + QT_USE_NAMESPACE @implementation QCocoaApplicationDelegate { - bool startedQuit; NSObject <NSApplicationDelegate> *reflectionDelegate; bool inLaunch; } @@ -140,71 +143,30 @@ QT_USE_NAMESPACE return [[self.dockMenu retain] autorelease]; } -- (BOOL)canQuit -{ - [[NSApp mainMenu] cancelTracking]; - - bool handle_quit = true; - NSMenuItem *quitMenuItem = [[QT_MANGLE_NAMESPACE(QCocoaMenuLoader) sharedMenuLoader] quitMenuItem]; - if (!QGuiApplicationPrivate::instance()->modalWindowList.isEmpty() - && [quitMenuItem isEnabled]) { - int visible = 0; - const QWindowList tlws = QGuiApplication::topLevelWindows(); - for (int i = 0; i < tlws.size(); ++i) { - if (tlws.at(i)->isVisible()) - ++visible; - } - handle_quit = (visible <= 1); - } - - if (handle_quit) { - QCloseEvent ev; - QGuiApplication::sendEvent(qGuiApp, &ev); - if (ev.isAccepted()) { - return YES; - } - } - - return NO; -} - // This function will only be called when NSApp is actually running. - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender { - // The reflection delegate gets precedence - if (reflectionDelegate) { - if ([reflectionDelegate respondsToSelector:@selector(applicationShouldTerminate:)]) - return [reflectionDelegate applicationShouldTerminate:sender]; - return NSTerminateNow; - } - - if ([self canQuit]) { - if (!startedQuit) { - startedQuit = true; - // Close open windows. This is done in order to deliver de-expose - // events while the event loop is still running. - const QWindowList topLevels = QGuiApplication::topLevelWindows(); - for (int i = 0; i < topLevels.size(); ++i) { - QWindow *topLevelWindow = topLevels.at(i); - // Already closed windows will not have a platform window, skip those - if (topLevelWindow->handle()) - QWindowSystemInterface::handleCloseEvent(topLevelWindow); - } - QWindowSystemInterface::flushWindowSystemEvents(); - - QGuiApplication::exit(0); - startedQuit = false; - } - } + if ([reflectionDelegate respondsToSelector:_cmd]) + return [reflectionDelegate applicationShouldTerminate:sender]; if (QGuiApplicationPrivate::instance()->threadData->eventLoops.isEmpty()) { - // INVARIANT: No event loop is executing. This probably - // means that Qt is used as a plugin, or as a part of a native - // Cocoa application. In any case it should be fine to - // terminate now: + // No event loop is executing. This probably means that Qt is used as a plugin, + // or as a part of a native Cocoa application. In any case it should be fine to + // terminate now. + qCDebug(lcQpaApplication) << "No running event loops, terminating now"; return NSTerminateNow; } + if (!QWindowSystemInterface::handleApplicationTermination<QWindowSystemInterface::SynchronousDelivery>()) { + qCDebug(lcQpaApplication) << "Application termination canceled"; + return NSTerminateCancel; + } + + // Even if the application termination was accepted by the application we can't + // return NSTerminateNow, as that would trigger AppKit to ultimately call exit(). + // We need to ensure that the runloop continues spinning so that we can return + // from our own event loop back to main(), and exit from there. + qCDebug(lcQpaApplication) << "Termination accepted, but returning to runloop for exit through main()"; return NSTerminateCancel; } @@ -228,10 +190,6 @@ QT_USE_NAMESPACE */ NSAppleEventManager *eventManager = [NSAppleEventManager sharedAppleEventManager]; [eventManager setEventHandler:self - andSelector:@selector(appleEventQuit:withReplyEvent:) - forEventClass:kCoreEventClass - andEventID:kAEQuitApplication]; - [eventManager setEventHandler:self andSelector:@selector(getUrl:withReplyEvent:) forEventClass:kInternetEventClass andEventID:kAEGetURL]; @@ -241,7 +199,6 @@ QT_USE_NAMESPACE - (void)removeAppleEventHandlers { NSAppleEventManager *eventManager = [NSAppleEventManager sharedAppleEventManager]; - [eventManager removeEventHandlerForEventClass:kCoreEventClass andEventID:kAEQuitApplication]; [eventManager removeEventHandlerForEventClass:kInternetEventClass andEventID:kAEGetURL]; } @@ -282,26 +239,22 @@ QT_USE_NAMESPACE QWindowSystemInterface::handleFileOpenEvent(qtFileName); } - if (reflectionDelegate && - [reflectionDelegate respondsToSelector:@selector(application:openFiles:)]) + if ([reflectionDelegate respondsToSelector:_cmd]) [reflectionDelegate application:sender openFiles:filenames]; } - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender { - // If we have a reflection delegate, that will get to call the shots. - if (reflectionDelegate - && [reflectionDelegate respondsToSelector: - @selector(applicationShouldTerminateAfterLastWindowClosed:)]) + if ([reflectionDelegate respondsToSelector:_cmd]) return [reflectionDelegate applicationShouldTerminateAfterLastWindowClosed:sender]; + return NO; // Someday qApp->quitOnLastWindowClosed(); when QApp and NSApp work closer together. } - (void)applicationDidBecomeActive:(NSNotification *)notification { - if (reflectionDelegate - && [reflectionDelegate respondsToSelector:@selector(applicationDidBecomeActive:)]) + if ([reflectionDelegate respondsToSelector:_cmd]) [reflectionDelegate applicationDidBecomeActive:notification]; QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationActive); @@ -309,8 +262,7 @@ QT_USE_NAMESPACE - (void)applicationDidResignActive:(NSNotification *)notification { - if (reflectionDelegate - && [reflectionDelegate respondsToSelector:@selector(applicationDidResignActive:)]) + if ([reflectionDelegate respondsToSelector:_cmd]) [reflectionDelegate applicationDidResignActive:notification]; QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationInactive); @@ -318,10 +270,7 @@ QT_USE_NAMESPACE - (BOOL)applicationShouldHandleReopen:(NSApplication *)theApplication hasVisibleWindows:(BOOL)flag { - Q_UNUSED(theApplication); - Q_UNUSED(flag); - if (reflectionDelegate - && [reflectionDelegate respondsToSelector:@selector(applicationShouldHandleReopen:hasVisibleWindows:)]) + if ([reflectionDelegate respondsToSelector:_cmd]) return [reflectionDelegate applicationShouldHandleReopen:theApplication hasVisibleWindows:flag]; /* @@ -354,16 +303,13 @@ QT_USE_NAMESPACE - (BOOL)respondsToSelector:(SEL)aSelector { - BOOL result = [super respondsToSelector:aSelector]; - if (!result && reflectionDelegate) - result = [reflectionDelegate respondsToSelector:aSelector]; - return result; + return [super respondsToSelector:aSelector] || [reflectionDelegate respondsToSelector:aSelector]; } - (void)forwardInvocation:(NSInvocation *)invocation { SEL invocationSelector = [invocation selector]; - if (reflectionDelegate && [reflectionDelegate respondsToSelector:invocationSelector]) + if ([reflectionDelegate respondsToSelector:invocationSelector]) [invocation invokeWithTarget:reflectionDelegate]; else [self doesNotRecognizeSelector:invocationSelector]; @@ -375,14 +321,6 @@ QT_USE_NAMESPACE NSString *urlString = [[event paramDescriptorForKeyword:keyDirectObject] stringValue]; QWindowSystemInterface::handleFileOpenEvent(QUrl(QString::fromNSString(urlString))); } - -- (void)appleEventQuit:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent -{ - Q_UNUSED(event); - Q_UNUSED(replyEvent); - [NSApp terminate:self]; -} - @end @implementation QCocoaApplicationDelegate (Menus) diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.mm b/src/plugins/platforms/cocoa/qcocoabackingstore.mm index 5550f0586b..b17302a640 100644 --- a/src/plugins/platforms/cocoa/qcocoabackingstore.mm +++ b/src/plugins/platforms/cocoa/qcocoabackingstore.mm @@ -195,7 +195,7 @@ void QNSWindowBackingStore::flush(QWindow *window, const QRegion ®ion, const // context is set up correctly (coordinate system, clipping, etc). Outside // of the normal display cycle there is no focused view, as explained above, // so we have to handle it manually. There's also a corner case inside the - // normal display cycle due to way QWidgetBackingStore composits native child + // normal display cycle due to way QWidgetRepaintManager composits native child // widgets, where we'll get a flush of a native child during the drawRect of // its parent/ancestor, and the parent/ancestor being the one locked by AppKit. // In this case we also need to lock and unlock focus manually. @@ -560,17 +560,26 @@ void QCALayerBackingStore::flush(QWindow *flushedWindow, const QRegion ®ion, flushedView.layer.contents = nil; } - qCInfo(lcQpaBackingStore) << "Flushing" << backBufferSurface - << "to" << flushedView.layer << "of" << flushedView; - - flushedView.layer.contents = backBufferSurface; + if (flushedView == backingStoreView) { + qCInfo(lcQpaBackingStore) << "Flushing" << backBufferSurface + << "to" << flushedView.layer << "of" << flushedView; + flushedView.layer.contents = backBufferSurface; + } else { + auto subviewRect = [flushedView convertRect:flushedView.bounds toView:backingStoreView]; + auto scale = flushedView.layer.contentsScale; + subviewRect = CGRectApplyAffineTransform(subviewRect, CGAffineTransformMakeScale(scale, scale)); + + // We make a copy of the image data up front, which means we don't + // need to mark the IOSurface as being in use. FIXME: Investigate + // if there's a cheaper way to get sub-image data to a layer. + m_buffers.back()->lock(QPlatformGraphicsBuffer::SWReadAccess); + QImage subImage = m_buffers.back()->asImage()->copy(QRectF::fromCGRect(subviewRect).toRect()); + m_buffers.back()->unlock(); - if (flushedView != backingStoreView) { - const CGSize backingStoreSize = backingStoreView.bounds.size; - flushedView.layer.contentsRect = CGRectApplyAffineTransform( - [flushedView convertRect:flushedView.bounds toView:backingStoreView], - // The contentsRect is in unit coordinate system - CGAffineTransformMakeScale(1.0 / backingStoreSize.width, 1.0 / backingStoreSize.height)); + qCInfo(lcQpaBackingStore) << "Flushing" << subImage + << "to" << flushedView.layer << "of subview" << flushedView; + QCFType<CGImageRef> cgImage = subImage.toCGImage(); + flushedView.layer.contents = (__bridge id)static_cast<CGImageRef>(cgImage); } // Since we may receive multiple flushes before a new frame is started, we do not diff --git a/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm index d7850b1481..c9fa035d87 100644 --- a/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm +++ b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm @@ -293,7 +293,7 @@ class QCocoaColorPanel public: QCocoaColorPanel() { - mDelegate = [[QT_MANGLE_NAMESPACE(QNSColorPanelDelegate) alloc] init]; + mDelegate = [[QNSColorPanelDelegate alloc] init]; } ~QCocoaColorPanel() @@ -366,7 +366,7 @@ public: } private: - QT_MANGLE_NAMESPACE(QNSColorPanelDelegate) *mDelegate; + QNSColorPanelDelegate *mDelegate; }; Q_GLOBAL_STATIC(QCocoaColorPanel, sharedColorPanel) diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm index d3bb0711f0..e87fc39c42 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm +++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm @@ -881,7 +881,7 @@ void QCocoaEventDispatcherPrivate::processPostedEvents() return; } - int serial = serialNumber.load(); + int serial = serialNumber.loadRelaxed(); if (!threadData->canWait || (serial != lastSerial)) { lastSerial = serial; QCoreApplication::sendPostedEvents(); diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.h b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.h index 2ddda14289..dd0afbefe6 100644 --- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.h +++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.h @@ -43,10 +43,16 @@ #include <QObject> #include <QtWidgets/qtwidgetsglobal.h> #include <qpa/qplatformdialoghelper.h> +#include <QtCore/private/qcore_mac_p.h> + +#import <AppKit/NSSavePanel.h> QT_REQUIRE_CONFIG(filedialog); -Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate)); +@interface QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) : NSObject<NSOpenSavePanelDelegate> +@end + +QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSOpenSavePanelDelegate); QT_BEGIN_NAMESPACE @@ -84,7 +90,7 @@ public: void QNSOpenSavePanelDelegate_filterSelected(int menuIndex); private: - QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *mDelegate; + QNSOpenSavePanelDelegate *mDelegate; QUrl mDir; }; diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm index d1695ea860..6aa21d78d1 100644 --- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm +++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm @@ -51,7 +51,6 @@ #include "qt_mac_p.h" #include "qcocoahelpers.h" #include "qcocoaeventdispatcher.h" -#include <qregexp.h> #include <qbuffer.h> #include <qdebug.h> #include <qstringlist.h> @@ -77,27 +76,6 @@ QT_USE_NAMESPACE typedef QSharedPointer<QFileDialogOptions> SharedPointerFileDialogOptions; -@interface QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) - : NSObject<NSOpenSavePanelDelegate> - -- (NSString *)strip:(const QString &)label; -- (BOOL)panel:(id)sender shouldEnableURL:(NSURL *)url; -- (void)filterChanged:(id)sender; -- (void)showModelessPanel; -- (BOOL)runApplicationModalPanel; -- (void)showWindowModalSheet:(QWindow *)docWidget; -- (void)updateProperties; -- (QStringList)acceptableExtensionsForSave; -- (QString)removeExtensions:(const QString &)filter; -- (void)createTextField; -- (void)createPopUpButton:(const QString &)selectedFilter hideDetails:(BOOL)hideDetails; -- (QStringList)findStrippedFilterWithVisualFilterName:(QString)name; -- (void)createAccessory; - -@end - -QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSOpenSavePanelDelegate); - @implementation QNSOpenSavePanelDelegate { @public NSOpenPanel *mOpenPanel; @@ -215,7 +193,7 @@ static QString strippedText(QString s) NSString *filepath = info.filePath().toNSString(); NSURL *url = [NSURL fileURLWithPath:filepath isDirectory:info.isDir()]; bool selectable = (mOptions->acceptMode() == QFileDialogOptions::AcceptSave) - || [self panel:nil shouldEnableURL:url]; + || [self panel:mOpenPanel shouldEnableURL:url]; [self updateProperties]; [mSavePanel setNameFieldStringValue:selectable ? info.fileName().toNSString() : @""]; @@ -234,7 +212,7 @@ static QString strippedText(QString s) NSString *filepath = info.filePath().toNSString(); NSURL *url = [NSURL fileURLWithPath:filepath isDirectory:info.isDir()]; bool selectable = (mOptions->acceptMode() == QFileDialogOptions::AcceptSave) - || [self panel:nil shouldEnableURL:url]; + || [self panel:mSavePanel shouldEnableURL:url]; [mSavePanel setDirectoryURL: [NSURL fileURLWithPath:mCurrentDir]]; [mSavePanel setNameFieldStringValue:selectable ? info.fileName().toNSString() : @""]; @@ -264,7 +242,7 @@ static QString strippedText(QString s) NSString *filepath = info.filePath().toNSString(); NSURL *url = [NSURL fileURLWithPath:filepath isDirectory:info.isDir()]; bool selectable = (mOptions->acceptMode() == QFileDialogOptions::AcceptSave) - || [self panel:nil shouldEnableURL:url]; + || [self panel:mSavePanel shouldEnableURL:url]; [self updateProperties]; [mSavePanel setDirectoryURL: [NSURL fileURLWithPath:mCurrentDir]]; diff --git a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm index 8c0af97a68..7748c304e3 100644 --- a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm +++ b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm @@ -283,7 +283,7 @@ class QCocoaFontPanel public: QCocoaFontPanel() { - mDelegate = [[QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) alloc] init]; + mDelegate = [[QNSFontPanelDelegate alloc] init]; } ~QCocoaFontPanel() @@ -356,7 +356,7 @@ public: } private: - QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *mDelegate; + QNSFontPanelDelegate *mDelegate; }; Q_GLOBAL_STATIC(QCocoaFontPanel, sharedFontPanel) diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.h b/src/plugins/platforms/cocoa/qcocoaglcontext.h index bb309c0713..4210a4ed3f 100644 --- a/src/plugins/platforms/cocoa/qcocoaglcontext.h +++ b/src/plugins/platforms/cocoa/qcocoaglcontext.h @@ -50,6 +50,8 @@ QT_BEGIN_NAMESPACE +class QCocoaWindow; + class QCocoaGLContext : public QPlatformOpenGLContext { public: @@ -76,12 +78,12 @@ private: static NSOpenGLPixelFormat *pixelFormatForSurfaceFormat(const QSurfaceFormat &format); bool setDrawable(QPlatformSurface *surface); + void prepareDrawable(QCocoaWindow *platformWindow); void updateSurfaceFormat(); NSOpenGLContext *m_context = nil; NSOpenGLContext *m_shareContext = nil; QSurfaceFormat m_format; - bool m_didCheckForSoftwareContext = false; QVarLengthArray<QMacNotificationObserver, 3> m_updateObservers; QAtomicInt m_needsUpdate = false; }; diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.mm b/src/plugins/platforms/cocoa/qcocoaglcontext.mm index ba7d12ce30..b312e033cd 100644 --- a/src/plugins/platforms/cocoa/qcocoaglcontext.mm +++ b/src/plugins/platforms/cocoa/qcocoaglcontext.mm @@ -223,12 +223,10 @@ NSOpenGLPixelFormat *QCocoaGLContext::pixelFormatForSurfaceFormat(const QSurface attrs << NSOpenGLPFAAllowOfflineRenderers; } - // FIXME: Pull this information out of the NSView - QByteArray useLayer = qgetenv("QT_MAC_WANTS_LAYER"); - if (!useLayer.isEmpty() && useLayer.toInt() > 0) { - // Disable the software rendering fallback. This makes compositing - // OpenGL and raster NSViews using Core Animation layers possible. - attrs << NSOpenGLPFANoRecovery; + if (qGuiApp->testAttribute(Qt::AA_UseSoftwareOpenGL)) { + // kCGLRendererGenericFloatID is the modern software renderer on macOS, + // as opposed to kCGLRendererGenericID, which is deprecated. + attrs << NSOpenGLPFARendererID << kCGLRendererGenericFloatID; } attrs << 0; // 0-terminate array @@ -368,23 +366,6 @@ bool QCocoaGLContext::makeCurrent(QPlatformSurface *surface) [m_context makeCurrentContext]; if (surface->surface()->surfaceClass() == QSurface::Window) { - // Disable high-resolution surfaces when using the software renderer, which has the - // problem that the system silently falls back to a to using a low-resolution buffer - // when a high-resolution buffer is requested. This is not detectable using the NSWindow - // convertSizeToBacking and backingScaleFactor APIs. A typical result of this is that Qt - // will display a quarter of the window content when running in a virtual machine. - if (!m_didCheckForSoftwareContext) { - // FIXME: This ensures we check only once per context, - // but the context may be used for multiple surfaces. - m_didCheckForSoftwareContext = true; - - const GLubyte* renderer = glGetString(GL_RENDERER); - if (qstrcmp((const char *)renderer, "Apple Software Renderer") == 0) { - NSView *view = static_cast<QCocoaWindow *>(surface)->m_view; - [view setWantsBestResolutionOpenGLSurface:NO]; - } - } - if (m_needsUpdate.fetchAndStoreRelaxed(false)) update(); } @@ -413,11 +394,14 @@ bool QCocoaGLContext::setDrawable(QPlatformSurface *surface) } Q_ASSERT(surface->surface()->surfaceClass() == QSurface::Window); - QNSView *view = qnsview_cast(static_cast<QCocoaWindow *>(surface)->view()); + auto *cocoaWindow = static_cast<QCocoaWindow *>(surface); + QNSView *view = qnsview_cast(cocoaWindow->view()); if (view == m_context.view) return true; + prepareDrawable(cocoaWindow); + // Setting the drawable may happen on a separate thread as a result of // a call to makeCurrent, so we need to set up the observers before we // associate the view with the context. That way we will guarantee that @@ -460,6 +444,30 @@ bool QCocoaGLContext::setDrawable(QPlatformSurface *surface) return true; } +void QCocoaGLContext::prepareDrawable(QCocoaWindow *platformWindow) +{ + // We generally want high-DPI GL surfaces, unless the user has explicitly disabled them + bool prefersBestResolutionOpenGLSurface = qt_mac_resolveOption(YES, + platformWindow->window(), "_q_mac_wantsBestResolutionOpenGLSurface", + "QT_MAC_WANTS_BEST_RESOLUTION_OPENGL_SURFACE"); + + auto *view = platformWindow->view(); + + // The only case we have to opt out ourselves is when using the Apple software renderer + // in combination with surface-backed views, as these together do not support high-DPI. + if (prefersBestResolutionOpenGLSurface) { + int rendererID = 0; + [m_context getValues:&rendererID forParameter:NSOpenGLContextParameterCurrentRendererID]; + bool isSoftwareRenderer = (rendererID & kCGLRendererIDMatchingMask) == kCGLRendererGenericFloatID; + if (isSoftwareRenderer && !view.layer) { + qCInfo(lcQpaOpenGLContext) << "Disabling high resolution GL surface due to software renderer"; + prefersBestResolutionOpenGLSurface = false; + } + } + + view.wantsBestResolutionOpenGLSurface = prefersBestResolutionOpenGLSurface; +} + // NSOpenGLContext is not re-entrant. Even when using separate contexts per thread, // view, and window, calls into the API will still deadlock. For more information // see https://openradar.appspot.com/37064579 @@ -491,6 +499,21 @@ void QCocoaGLContext::swapBuffers(QPlatformSurface *surface) return; } + if (m_context.view.layer) { + // Flushing an NSOpenGLContext will hit the screen immediately, ignoring + // any Core Animation transactions in place. This may result in major + // visual artifacts if the flush happens out of sync with the size + // of the layer, view, and window reflected by other parts of the UI, + // e.g. if the application flushes in the resize event or a timer during + // window resizing, instead of in the expose event. + auto *cocoaWindow = static_cast<QCocoaWindow *>(surface); + if (cocoaWindow->geometry().size() != cocoaWindow->m_exposedRect.size()) { + qCInfo(lcQpaOpenGLContext) << "Window exposed size does not match geometry (yet)." + << "Skipping flush to avoid visual artifacts."; + return; + } + } + QMutexLocker locker(&s_reentrancyMutex); [m_context flushBuffer]; } diff --git a/src/plugins/platforms/cocoa/qcocoamenu.h b/src/plugins/platforms/cocoa/qcocoamenu.h index a957710a88..1dccf0621c 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.h +++ b/src/plugins/platforms/cocoa/qcocoamenu.h @@ -44,8 +44,7 @@ #include <QtCore/QList> #include <qpa/qplatformmenu.h> #include "qcocoamenuitem.h" - -Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QCocoaNSMenu)); +#include "qcocoansmenu.h" QT_BEGIN_NAMESPACE @@ -107,7 +106,7 @@ private: void scheduleUpdate(); QList<QCocoaMenuItem *> m_menuItems; - QT_MANGLE_NAMESPACE(QCocoaNSMenu) *m_nativeMenu; + QCocoaNSMenu *m_nativeMenu; NSMenuItem *m_attachedItem; int m_updateTimer; bool m_enabled:1; diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.mm b/src/plugins/platforms/cocoa/qcocoamenubar.mm index 30bff78a36..363defdd28 100644 --- a/src/plugins/platforms/cocoa/qcocoamenubar.mm +++ b/src/plugins/platforms/cocoa/qcocoamenubar.mm @@ -278,12 +278,11 @@ void QCocoaMenuBar::updateMenuBarImmediately() // we still have to update the menubar. if ((win->flags() & Qt::WindowType_Mask) != Qt::Tool) return; - typedef QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) AppDelegate; NSApplication *app = [NSApplication sharedApplication]; - if (![app.delegate isKindOfClass:[AppDelegate class]]) + if (![app.delegate isKindOfClass:[QCocoaApplicationDelegate class]]) return; // We apply this logic _only_ during the startup. - AppDelegate *appDelegate = app.delegate; + QCocoaApplicationDelegate *appDelegate = app.delegate; if (!appDelegate.inLaunch) return; } @@ -403,3 +402,4 @@ QCocoaWindow *QCocoaMenuBar::cocoaWindow() const QT_END_NAMESPACE +#include "moc_qcocoamenubar.cpp" diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm index ef9b2659d2..c35cf6d799 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm +++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm @@ -53,6 +53,7 @@ #include <QtGui/private/qcoregraphics_p.h> #include <QtCore/QDebug> +#include <QtCore/QRegExp> QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoansmenu.h b/src/plugins/platforms/cocoa/qcocoansmenu.h index 6cbb6e4a01..0c77e2f1aa 100644 --- a/src/plugins/platforms/cocoa/qcocoansmenu.h +++ b/src/plugins/platforms/cocoa/qcocoansmenu.h @@ -59,31 +59,20 @@ QT_FORWARD_DECLARE_CLASS(QCocoaMenu); QT_FORWARD_DECLARE_CLASS(QCocoaMenuItem); @interface QT_MANGLE_NAMESPACE(QCocoaNSMenuDelegate) : NSObject <NSMenuDelegate> - + (instancetype)sharedMenuDelegate; - -- (NSMenuItem *)findItemInMenu:(NSMenu *)menu - forKey:(NSString *)key - modifiers:(NSUInteger)modifiers; - +- (NSMenuItem *)findItemInMenu:(NSMenu *)menu forKey:(NSString *)key modifiers:(NSUInteger)modifiers; @end @interface QT_MANGLE_NAMESPACE(QCocoaNSMenu) : NSMenu - @property (readonly, nonatomic) QCocoaMenu *platformMenu; - - (instancetype)initWithPlatformMenu:(QCocoaMenu *)menu; - @end @interface QT_MANGLE_NAMESPACE(QCocoaNSMenuItem) : NSMenuItem - @property (nonatomic) QCocoaMenuItem *platformMenuItem; - + (instancetype)separatorItemWithPlatformMenuItem:(QCocoaMenuItem *)menuItem; - (instancetype)initWithPlatformMenuItem:(QCocoaMenuItem *)menuItem; - (instancetype)init; - @end QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaNSMenu); diff --git a/src/plugins/platforms/cocoa/qcocoascreen.h b/src/plugins/platforms/cocoa/qcocoascreen.h index 491af2fe9c..7ec9a2b5af 100644 --- a/src/plugins/platforms/cocoa/qcocoascreen.h +++ b/src/plugins/platforms/cocoa/qcocoascreen.h @@ -68,6 +68,7 @@ public: qreal devicePixelRatio() const override { return m_devicePixelRatio; } QSizeF physicalSize() const override { return m_physicalSize; } QDpi logicalDpi() const override { return m_logicalDpi; } + QDpi logicalBaseDpi() const override { return m_logicalDpi; } qreal refreshRate() const override { return m_refreshRate; } QString name() const override { return m_name; } QPlatformCursor *cursor() const override { return m_cursor; } @@ -98,18 +99,18 @@ private: static void add(CGDirectDisplayID displayId); void remove(); - CGDirectDisplayID m_displayId = 0; + CGDirectDisplayID m_displayId = kCGNullDirectDisplay; QRect m_geometry; QRect m_availableGeometry; QDpi m_logicalDpi; - qreal m_refreshRate; - int m_depth; + qreal m_refreshRate = 0; + int m_depth = 0; QString m_name; QImage::Format m_format; QSizeF m_physicalSize; QCocoaCursor *m_cursor; - qreal m_devicePixelRatio; + qreal m_devicePixelRatio = 0; CVDisplayLinkRef m_displayLink = nullptr; dispatch_source_t m_displayLinkSource = nullptr; diff --git a/src/plugins/platforms/cocoa/qcocoascreen.mm b/src/plugins/platforms/cocoa/qcocoascreen.mm index 392099d083..40273bac84 100644 --- a/src/plugins/platforms/cocoa/qcocoascreen.mm +++ b/src/plugins/platforms/cocoa/qcocoascreen.mm @@ -54,6 +54,23 @@ QT_BEGIN_NAMESPACE +namespace CoreGraphics { + Q_NAMESPACE + enum DisplayChange { + Moved = kCGDisplayMovedFlag, + SetMain = kCGDisplaySetMainFlag, + SetMode = kCGDisplaySetModeFlag, + Added = kCGDisplayAddFlag, + Removed = kCGDisplayRemoveFlag, + Enabled = kCGDisplayEnabledFlag, + Disabled = kCGDisplayDisabledFlag, + Mirrored = kCGDisplayMirrorFlag, + UnMirrored = kCGDisplayUnMirrorFlag, + DesktopShapeChanged = kCGDisplayDesktopShapeChangedFlag + }; + Q_ENUM_NS(DisplayChange) +} + void QCocoaScreen::initializeScreens() { uint32_t displayCount = 0; @@ -73,6 +90,10 @@ void QCocoaScreen::initializeScreens() Q_UNUSED(userInfo); + qCDebug(lcQpaScreen).verbosity(0).nospace() << "Display reconfiguration" + << " (" << QFlags<CoreGraphics::DisplayChange>(flags) << ")" + << " for displayId=" << displayId; + QCocoaScreen *cocoaScreen = QCocoaScreen::get(displayId); if ((flags & kCGDisplayAddFlag) || !cocoaScreen) { @@ -93,22 +114,24 @@ void QCocoaScreen::initializeScreens() mainDisplay->updateProperties(); qCInfo(lcQpaScreen) << "Primary screen changed to" << mainDisplay; QWindowSystemInterface::handlePrimaryScreenChanged(mainDisplay); + if (cocoaScreen == mainDisplay) + return; // Already reconfigured } - if (cocoaScreen == mainDisplay) - return; // Already reconfigured - cocoaScreen->updateProperties(); - qCInfo(lcQpaScreen) << "Reconfigured" << cocoaScreen; + qCInfo(lcQpaScreen).nospace() << "Reconfigured " << + (primaryScreen() == cocoaScreen ? "primary " : "") + << cocoaScreen; } }, nullptr); } void QCocoaScreen::add(CGDirectDisplayID displayId) { + const bool isPrimary = CGDisplayIsMain(displayId); QCocoaScreen *cocoaScreen = new QCocoaScreen(displayId); - qCInfo(lcQpaScreen) << "Adding" << cocoaScreen; - QWindowSystemInterface::handleScreenAdded(cocoaScreen, CGDisplayIsMain(displayId)); + qCInfo(lcQpaScreen).nospace() << "Adding " << (isPrimary ? "new primary " : "") << cocoaScreen; + QWindowSystemInterface::handleScreenAdded(cocoaScreen, isPrimary); } QCocoaScreen::QCocoaScreen(CGDirectDisplayID displayId) @@ -127,7 +150,7 @@ void QCocoaScreen::cleanupScreens() void QCocoaScreen::remove() { - m_displayId = 0; // Prevent stale references during removal + m_displayId = kCGNullDirectDisplay; // Prevent stale references during removal // This may result in the application responding to QGuiApplication::screenRemoved // by moving the window to another screen, either by setGeometry, or by setScreen. @@ -140,6 +163,7 @@ void QCocoaScreen::remove() // QCocoaWindow::windowDidChangeScreen. At that point the window will appear to have // already changed its screen, but that's only true if comparing the Qt screens, // not when comparing the NSScreens. + qCInfo(lcQpaScreen).nospace() << "Removing " << (primaryScreen() == this ? "current primary " : "") << this; QWindowSystemInterface::handleScreenRemoved(this); } @@ -552,10 +576,10 @@ QPixmap QCocoaScreen::grabWindow(WId view, int x, int y, int width, int height) */ QCocoaScreen *QCocoaScreen::primaryScreen() { - auto screen = static_cast<QCocoaScreen *>(QGuiApplication::primaryScreen()->handle()); - Q_ASSERT_X(screen == get(CGMainDisplayID()), "QCocoaScreen", - "The application's primary screen should always be in sync with the main display"); - return screen; + // Note: The primary screen that Qt knows about may not match the current CGMainDisplayID() + // if macOS has not yet been able to inform us that the main display has changed, but we + // will update the primary screen accordingly once the reconfiguration callback comes in. + return static_cast<QCocoaScreen *>(QGuiApplication::primaryScreen()->handle()); } QList<QPlatformScreen*> QCocoaScreen::virtualSiblings() const @@ -597,7 +621,7 @@ NSScreen *QCocoaScreen::nativeScreen() const QCFType<CFUUIDRef> uuid = CGDisplayCreateUUIDFromDisplayID(m_displayId); for (NSScreen *screen in [NSScreen screens]) { - if (CGDisplayCreateUUIDFromDisplayID(screen.qt_displayId) == uuid) + if (QCFType<CFUUIDRef>(CGDisplayCreateUUIDFromDisplayID(screen.qt_displayId)) == uuid) return screen; } @@ -639,6 +663,7 @@ QDebug operator<<(QDebug debug, const QCocoaScreen *screen) debug << ", geometry=" << screen->geometry(); debug << ", dpr=" << screen->devicePixelRatio(); debug << ", name=" << screen->name(); + debug << ", displayId=" << screen->m_displayId; debug << ", native=" << screen->nativeScreen(); } debug << ')'; @@ -646,6 +671,8 @@ QDebug operator<<(QDebug debug, const QCocoaScreen *screen) } #endif // !QT_NO_DEBUG_STREAM +#include "qcocoascreen.moc" + QT_END_NAMESPACE @implementation NSScreen (QtExtras) diff --git a/src/plugins/platforms/cocoa/qcocoasystemsettings.mm b/src/plugins/platforms/cocoa/qcocoasystemsettings.mm index 9b6dc94d33..cb25bd7d81 100644 --- a/src/plugins/platforms/cocoa/qcocoasystemsettings.mm +++ b/src/plugins/platforms/cocoa/qcocoasystemsettings.mm @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2019 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the plugins of the Qt Toolkit. @@ -52,6 +52,8 @@ @property (class, strong, readonly) NSColor *unemphasizedSelectedTextColor NS_AVAILABLE_MAC(10_14); @property (class, strong, readonly) NSColor *unemphasizedSelectedContentBackgroundColor NS_AVAILABLE_MAC(10_14); @property (class, strong, readonly) NSArray<NSColor *> *alternatingContentBackgroundColors NS_AVAILABLE_MAC(10_14); +// Missing from non-Mojave SDKs, even if introduced in 10.10 +@property (class, strong, readonly) NSColor *linkColor NS_AVAILABLE_MAC(10_10); @end #endif @@ -111,6 +113,8 @@ QPalette * qt_mac_createSystemPalette() palette->setBrush(QPalette::ToolTipBase, qt_mac_toQBrush([NSColor controlColor])); + palette->setColor(QPalette::Normal, QPalette::Link, qt_mac_toQColor([NSColor linkColor])); + return palette; } diff --git a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm index db64702b8d..a5b42ac4e3 100644 --- a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm +++ b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm @@ -80,6 +80,8 @@ #include <qimagewriter.h> #include <qdebug.h> +#include <QtCore/private/qcore_mac_p.h> + #include "qcocoamenu.h" #include "qt_mac_p.h" @@ -92,8 +94,6 @@ QT_USE_NAMESPACE -@class QT_MANGLE_NAMESPACE(QNSImageView); - @interface QT_MANGLE_NAMESPACE(QNSStatusItem) : NSObject <NSUserNotificationCenterDelegate> @property (nonatomic, assign) QCocoaMenu *menu; @property (nonatomic, assign) QIcon icon; @@ -104,12 +104,13 @@ QT_USE_NAMESPACE - (void)doubleClickSelector:(id)sender; @end +QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSStatusItem); + @interface QT_MANGLE_NAMESPACE(QNSImageView) : NSImageView @property (nonatomic, assign) BOOL down; -@property (nonatomic, assign) QT_MANGLE_NAMESPACE(QNSStatusItem) *parent; +@property (nonatomic, assign) QNSStatusItem *parent; @end -QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSStatusItem); QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSImageView); QT_BEGIN_NAMESPACE @@ -360,7 +361,7 @@ QT_END_NAMESPACE @implementation QNSStatusItem { QCocoaSystemTrayIcon *systray; NSStatusItem *item; - QT_MANGLE_NAMESPACE(QNSImageView) *imageCell; + QNSImageView *imageCell; } @synthesize menu = menu; diff --git a/src/plugins/platforms/cocoa/qcocoatheme.h b/src/plugins/platforms/cocoa/qcocoatheme.h index 788b616e78..a00cbdfea3 100644 --- a/src/plugins/platforms/cocoa/qcocoatheme.h +++ b/src/plugins/platforms/cocoa/qcocoatheme.h @@ -43,8 +43,6 @@ #include <QtCore/QHash> #include <qpa/qplatformtheme.h> -Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QCocoaThemeAppAppearanceObserver)); - #include <QtCore/private/qcore_mac_p.h> QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h index c6ce6e6819..fef72bc496 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.h +++ b/src/plugins/platforms/cocoa/qcocoawindow.h @@ -161,7 +161,6 @@ public: Q_NOTIFICATION_HANDLER(NSWindowDidOrderOffScreenNotification) void windowDidOrderOffScreen(); Q_NOTIFICATION_HANDLER(NSWindowDidChangeOcclusionStateNotification) void windowDidChangeOcclusionState(); Q_NOTIFICATION_HANDLER(NSWindowDidChangeScreenNotification) void windowDidChangeScreen(); - Q_NOTIFICATION_HANDLER(NSWindowDidChangeBackingPropertiesNotification) void windowDidChangeBackingProperties(); Q_NOTIFICATION_HANDLER(NSWindowWillCloseNotification) void windowWillClose(); bool windowShouldClose(); diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index db4bc12210..a744a86695 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -1262,17 +1262,6 @@ void QCocoaWindow::windowDidChangeScreen() currentScreen->requestUpdate(); } } -/* - The window's backing scale factor or color space has changed. -*/ -void QCocoaWindow::windowDidChangeBackingProperties() -{ - // Ideally we would plumb this thought QPA in a way that lets clients - // invalidate their own caches, and recreate QBackingStore. For now we - // trigger an expose, and let QCocoaBackingStore deal with its own - // buffer invalidation. - [m_view setNeedsDisplay:YES]; -} void QCocoaWindow::windowWillClose() { @@ -1286,14 +1275,11 @@ void QCocoaWindow::windowWillClose() bool QCocoaWindow::windowShouldClose() { qCDebug(lcQpaWindow) << "QCocoaWindow::windowShouldClose" << window(); - // This callback should technically only determine if the window - // should (be allowed to) close, but since our QPA API to determine - // that also involves actually closing the window we do both at the - // same time, instead of doing the latter in windowWillClose. - bool accepted = false; - QWindowSystemInterface::handleCloseEvent(window(), &accepted); - QWindowSystemInterface::flushWindowSystemEvents(); - return accepted; + // This callback should technically only determine if the window + // should (be allowed to) close, but since our QPA API to determine + // that also involves actually closing the window we do both at the + // same time, instead of doing the latter in windowWillClose. + return QWindowSystemInterface::handleCloseEvent<QWindowSystemInterface::SynchronousDelivery>(window()); } // ----------------------------- QPA forwarding ----------------------------- diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h index b40dfe0d14..74d0735b4c 100644 --- a/src/plugins/platforms/cocoa/qnsview.h +++ b/src/plugins/platforms/cocoa/qnsview.h @@ -51,37 +51,30 @@ class QCocoaGLContext; class QPointF; QT_END_NAMESPACE -Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper)); -Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QCocoaNSMenuItem)); - @interface QT_MANGLE_NAMESPACE(QNSView) : NSView - @property (nonatomic, retain) NSCursor *cursor; - - (instancetype)initWithCocoaWindow:(QCocoaWindow *)platformWindow; - - (void)convertFromScreen:(NSPoint)mouseLocation toWindowPoint:(QPointF *)qtWindowPoint andScreenPoint:(QPointF *)qtScreenPoint; - @end -@interface QT_MANGLE_NAMESPACE(QNSView) (MouseAPI) +QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSView); + +@interface QNSView (MouseAPI) - (void)handleFrameStrutMouseEvent:(NSEvent *)theEvent; - (void)resetMouseButtons; @end -@interface QT_MANGLE_NAMESPACE(QNSView) (KeysAPI) +@interface QNSView (KeysAPI) + (Qt::KeyboardModifiers)convertKeyModifiers:(ulong)modifierFlags; @end -@interface QT_MANGLE_NAMESPACE(QNSView) (ComplexTextAPI) +@interface QNSView (ComplexTextAPI) - (void)unmarkText; - (void)cancelComposingText; @end -@interface QT_MANGLE_NAMESPACE(QNSView) (QtExtras) +@interface QNSView (QtExtras) @property (nonatomic, readonly) QCocoaWindow *platformWindow; @end -QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSView); - #endif //QNSVIEW_H diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 5309449dce..a6e5ca5f7b 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -66,13 +66,13 @@ #include "qcocoaintegration.h" // Private interface -@interface QT_MANGLE_NAMESPACE(QNSView) () +@interface QNSView () - (BOOL)isTransparentForUserInput; @property (assign) NSView* previousSuperview; @property (assign) NSWindow* previousWindow; @end -@interface QT_MANGLE_NAMESPACE(QNSView) (Drawing) <CALayerDelegate> +@interface QNSView (Drawing) <CALayerDelegate> - (void)initDrawing; @end @@ -84,7 +84,9 @@ - (void)cursorUpdate:(NSEvent *)theEvent; @end -@interface QT_MANGLE_NAMESPACE(QNSView) (Mouse) +QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSViewMouseMoveHelper); + +@interface QNSView (Mouse) - (void)initMouse; - (NSPoint)screenMousePoint:(NSEvent *)theEvent; - (void)mouseMovedImpl:(NSEvent *)theEvent; @@ -92,28 +94,28 @@ - (void)mouseExitedImpl:(NSEvent *)theEvent; @end -@interface QT_MANGLE_NAMESPACE(QNSView) (Touch) +@interface QNSView (Touch) @end -@interface QT_MANGLE_NAMESPACE(QNSView) (Tablet) +@interface QNSView (Tablet) - (bool)handleTabletEvent:(NSEvent *)theEvent; @end -@interface QT_MANGLE_NAMESPACE(QNSView) (Gestures) +@interface QNSView (Gestures) @end -@interface QT_MANGLE_NAMESPACE(QNSView) (Dragging) +@interface QNSView (Dragging) -(void)registerDragTypes; @end -@interface QT_MANGLE_NAMESPACE(QNSView) (Keys) +@interface QNSView (Keys) @end -@interface QT_MANGLE_NAMESPACE(QNSView) (ComplexText) <NSTextInputClient> +@interface QNSView (ComplexText) <NSTextInputClient> - (void)textInputContextKeyboardSelectionDidChangeNotification:(NSNotification *)textInputContextKeyboardSelectionDidChangeNotification; @end -@implementation QT_MANGLE_NAMESPACE(QNSView) { +@implementation QNSView { QPointer<QCocoaWindow> m_platformWindow; Qt::MouseButtons m_buttons; Qt::MouseButtons m_acceptedMouseDowns; @@ -125,7 +127,7 @@ bool m_sendUpAsRightButton; Qt::KeyboardModifiers m_currentWheelModifiers; NSString *m_inputSource; - QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper) *m_mouseMoveHelper; + QNSViewMouseMoveHelper *m_mouseMoveHelper; bool m_resendKeyEvent; bool m_scrolling; bool m_updatingDrag; @@ -379,7 +381,7 @@ // ----------------------------------------------------- -@implementation QT_MANGLE_NAMESPACE(QNSView) (QtExtras) +@implementation QNSView (QtExtras) - (QCocoaWindow*)platformWindow { diff --git a/src/plugins/platforms/cocoa/qnsview_accessibility.mm b/src/plugins/platforms/cocoa/qnsview_accessibility.mm index 32ec0b74d4..7041e14da7 100644 --- a/src/plugins/platforms/cocoa/qnsview_accessibility.mm +++ b/src/plugins/platforms/cocoa/qnsview_accessibility.mm @@ -47,7 +47,7 @@ #import <AppKit/NSAccessibility.h> -@implementation QT_MANGLE_NAMESPACE(QNSView) (Accessibility) +@implementation QNSView (Accessibility) - (id)childAccessibleElement { diff --git a/src/plugins/platforms/cocoa/qnsview_complextext.mm b/src/plugins/platforms/cocoa/qnsview_complextext.mm index 6ff9b26ca4..5926840cf3 100644 --- a/src/plugins/platforms/cocoa/qnsview_complextext.mm +++ b/src/plugins/platforms/cocoa/qnsview_complextext.mm @@ -39,7 +39,7 @@ // This file is included from qnsview.mm, and only used to organize the code -@implementation QT_MANGLE_NAMESPACE(QNSView) (ComplexTextAPI) +@implementation QNSView (ComplexTextAPI) - (void)cancelComposingText { @@ -80,7 +80,7 @@ @end -@implementation QT_MANGLE_NAMESPACE(QNSView) (ComplexText) +@implementation QNSView (ComplexText) - (void)insertNewline:(id)sender { diff --git a/src/plugins/platforms/cocoa/qnsview_dragging.mm b/src/plugins/platforms/cocoa/qnsview_dragging.mm index 41b96b2df6..650612e7ff 100644 --- a/src/plugins/platforms/cocoa/qnsview_dragging.mm +++ b/src/plugins/platforms/cocoa/qnsview_dragging.mm @@ -39,7 +39,7 @@ // This file is included from qnsview.mm, and only used to organize the code -@implementation QT_MANGLE_NAMESPACE(QNSView) (Dragging) +@implementation QNSView (Dragging) -(void)registerDragTypes { diff --git a/src/plugins/platforms/cocoa/qnsview_drawing.mm b/src/plugins/platforms/cocoa/qnsview_drawing.mm index d2e6f848a0..2fd63fad67 100644 --- a/src/plugins/platforms/cocoa/qnsview_drawing.mm +++ b/src/plugins/platforms/cocoa/qnsview_drawing.mm @@ -39,24 +39,11 @@ // This file is included from qnsview.mm, and only used to organize the code -@implementation QT_MANGLE_NAMESPACE(QNSView) (Drawing) +@implementation QNSView (Drawing) - (void)initDrawing { - self.wantsLayer = [self layerExplicitlyRequested] - || [self shouldUseMetalLayer] - || [self layerEnabledByMacOS]; - - // Enable high-DPI OpenGL for retina displays. Enabling has the side - // effect that Cocoa will start calling glViewport(0, 0, width, height), - // overriding any glViewport calls in application code. This is usually not a - // problem, except if the application wants to have a "custom" viewport. - // (like the hellogl example) - if (m_platformWindow->window()->supportsOpenGL()) { - self.wantsBestResolutionOpenGLSurface = qt_mac_resolveOption(YES, m_platformWindow->window(), - "_q_mac_wantsBestResolutionOpenGLSurface", "QT_MAC_WANTS_BEST_RESOLUTION_OPENGL_SURFACE"); - // See also QCocoaGLContext::makeCurrent for software renderer workarounds. - } + [self updateLayerBacking]; } - (BOOL)isOpaque @@ -71,22 +58,13 @@ return YES; } -- (void)drawRect:(NSRect)dirtyRect -{ - Q_UNUSED(dirtyRect); - - if (!m_platformWindow) - return; +// ----------------------- Layer setup ----------------------- - QRegion exposedRegion; - const NSRect *dirtyRects; - NSInteger numDirtyRects; - [self getRectsBeingDrawn:&dirtyRects count:&numDirtyRects]; - for (int i = 0; i < numDirtyRects; ++i) - exposedRegion += QRectF::fromCGRect(dirtyRects[i]).toRect(); - - qCDebug(lcQpaDrawing) << "[QNSView drawRect:]" << m_platformWindow->window() << exposedRegion; - m_platformWindow->handleExposeEvent(exposedRegion); +- (void)updateLayerBacking +{ + self.wantsLayer = [self layerEnabledByMacOS] + || [self layerExplicitlyRequested] + || [self shouldUseMetalLayer]; } - (BOOL)layerEnabledByMacOS @@ -123,40 +101,81 @@ return surfaceType == QWindow::MetalSurface || surfaceType == QWindow::VulkanSurface; } +/* + This method is called by AppKit when layer-backing is requested by + setting wantsLayer too YES (via -[NSView _updateLayerBackedness]), + or in cases where AppKit itself decides that a view should be + layer-backed. + + Note however that some code paths in AppKit will not go via this + method for creating the backing layer, and will instead create the + layer manually, and just call setLayer. An example of this is when + an NSOpenGLContext is attached to a view, in which case AppKit will + create a new layer in NSOpenGLContextSetLayerOnViewIfNecessary. + + For this reason we leave the implementation of this override as + minimal as possible, only focusing on creating the appropriate + layer type, and then leave it up to setLayer to do the work of + making sure the layer is set up correctly. +*/ - (CALayer *)makeBackingLayer { if ([self shouldUseMetalLayer]) { // Check if Metal is supported. If it isn't then it's most likely // too late at this point and the QWindow will be non-functional, // but we can at least print a warning. - if (![MTLCreateSystemDefaultDevice() autorelease]) { - qWarning() << "QWindow initialization error: Metal is not supported"; - return [super makeBackingLayer]; + if ([MTLCreateSystemDefaultDevice() autorelease]) { + return [CAMetalLayer layer]; + } else { + qCWarning(lcQpaDrawing) << "Failed to create QWindow::MetalSurface." + << "Metal is not supported by any of the GPUs in this system."; } - - CAMetalLayer *layer = [CAMetalLayer layer]; - - // Set the contentsScale for the layer. This is normally done in - // viewDidChangeBackingProperties, however on startup that function - // is called before the layer is created here. The layer's drawableSize - // is updated from layoutSublayersOfLayer as usual. - layer.contentsScale = self.window.backingScaleFactor; - - return layer; } return [super makeBackingLayer]; } +/* + This method is called by AppKit whenever the view is asked to change + its layer, which can happen both as a result of enabling layer-backing, + or when a layer is set explicitly. The latter can happen both when a + view is layer-hosting, or when AppKit internals are switching out the + layer-backed view, as described above for makeBackingLayer. +*/ - (void)setLayer:(CALayer *)layer { - qCDebug(lcQpaDrawing) << "Making" << self << "layer-backed with" << layer - << "due to being" << ([self layerExplicitlyRequested] ? "explicitly requested" + qCDebug(lcQpaDrawing) << "Making" << self + << (self.wantsLayer ? "layer-backed" : "layer-hosted") + << "with" << layer << "due to being" << ([self layerExplicitlyRequested] ? "explicitly requested" : [self shouldUseMetalLayer] ? "needed by surface type" : "enabled by macOS"); + + if (layer.delegate && layer.delegate != self) { + qCWarning(lcQpaDrawing) << "Layer already has delegate" << layer.delegate + << "This delegate is responsible for all view updates for" << self; + } else { + layer.delegate = self; + } + [super setLayer:layer]; - layer.delegate = self; + + // When adding a view to a view hierarchy the backing properties will change + // which results in updating the contents scale, but in case of switching the + // layer on a view that's already in a view hierarchy we need to manually ensure + // the scale is up to date. + if (self.superview) + [self updateLayerContentsScale]; + + if (self.opaque && lcQpaDrawing().isDebugEnabled()) { + // If the view claims to be opaque we expect it to fill the entire + // layer with content, in which case we want to detect any areas + // where it doesn't. + layer.backgroundColor = NSColor.magentaColor.CGColor; + } + } +// ----------------------- Layer updates ----------------------- + - (NSViewLayerContentsRedrawPolicy)layerContentsRedrawPolicy { // We need to set this explicitly since the super implementation @@ -164,64 +183,106 @@ return NSViewLayerContentsRedrawDuringViewResize; } -#if 0 // Disabled until we enable lazy backingstore resizing - (NSViewLayerContentsPlacement)layerContentsPlacement { - // Always place the layer at top left without any automatic scaling, - // so that we can re-use larger layers when resizing a window down. + // Always place the layer at top left without any automatic scaling. + // This will highlight situations where we're missing content for the + // layer by not responding to the displayLayer: request synchronously. + // It also allows us to re-use larger layers when resizing a window down. return NSViewLayerContentsPlacementTopLeft; } -#endif -- (void)updateMetalLayerDrawableSize:(CAMetalLayer *)layer +- (void)viewDidChangeBackingProperties { - CGSize drawableSize = layer.bounds.size; - drawableSize.width *= layer.contentsScale; - drawableSize.height *= layer.contentsScale; - layer.drawableSize = drawableSize; + qCDebug(lcQpaDrawing) << "Backing properties changed for" << self; + + if (self.layer) + [self updateLayerContentsScale]; + + // Ideally we would plumb this situation through QPA in a way that lets + // clients invalidate their own caches, recreate QBackingStore, etc. + // For now we trigger an expose, and let QCocoaBackingStore deal with + // buffer invalidation internally. + [self setNeedsDisplay:YES]; } -- (void)layoutSublayersOfLayer:(CALayer *)layer +- (void)updateLayerContentsScale { - if ([layer isKindOfClass:CAMetalLayer.class]) - [self updateMetalLayerDrawableSize:static_cast<CAMetalLayer* >(layer)]; + // We expect clients to fill the layer with retina aware content, + // based on the devicePixelRatio of the QWindow, so we set the + // layer's content scale to match that. By going via devicePixelRatio + // instead of applying the NSWindow's backingScaleFactor, we also take + // into account OpenGL views with wantsBestResolutionOpenGLSurface set + // to NO. In this case the window will have a backingScaleFactor of 2, + // but the QWindow will have a devicePixelRatio of 1. + auto devicePixelRatio = m_platformWindow->devicePixelRatio(); + qCDebug(lcQpaDrawing) << "Updating" << self.layer << "content scale to" << devicePixelRatio; + self.layer.contentsScale = devicePixelRatio; } -- (void)displayLayer:(CALayer *)layer +/* + This method is called by AppKit to determine whether it should update + the contentScale of the layer to match the window backing scale. + + We always return NO since we're updating the contents scale manually. +*/ +- (BOOL)layer:(CALayer *)layer shouldInheritContentsScale:(CGFloat)scale fromWindow:(NSWindow *)window { - if (!NSThread.isMainThread) { - // Qt is calling AppKit APIs such as -[NSOpenGLContext setView:] on secondary threads, - // which we shouldn't do. This may result in AppKit (wrongly) triggering a display on - // the thread where we made the call, so block it here and defer to the main thread. - qCWarning(lcQpaDrawing) << "Display non non-main thread! Deferring to main thread"; - dispatch_async(dispatch_get_main_queue(), ^{ self.needsDisplay = YES; }); - return; - } + Q_UNUSED(layer); Q_UNUSED(scale); Q_UNUSED(window); + return NO; +} - Q_ASSERT(layer == self.layer); +// ----------------------- Draw callbacks ----------------------- + +/* + This method is called by AppKit for the non-layer case, where we are + drawing into the NSWindow's surface. +*/ +- (void)drawRect:(NSRect)dirtyBoundingRect +{ + Q_ASSERT_X(!self.layer, "QNSView", + "The drawRect code path should not be hit when we are layer backed"); if (!m_platformWindow) return; - qCDebug(lcQpaDrawing) << "[QNSView displayLayer]" << m_platformWindow->window(); + QRegion exposedRegion; + const NSRect *dirtyRects; + NSInteger numDirtyRects; + [self getRectsBeingDrawn:&dirtyRects count:&numDirtyRects]; + for (int i = 0; i < numDirtyRects; ++i) + exposedRegion += QRectF::fromCGRect(dirtyRects[i]).toRect(); - // FIXME: Find out if there's a way to resolve the dirty rect like in drawRect: - m_platformWindow->handleExposeEvent(QRectF::fromCGRect(self.bounds).toRect()); + if (exposedRegion.isEmpty()) + exposedRegion = QRectF::fromCGRect(dirtyBoundingRect).toRect(); + + qCDebug(lcQpaDrawing) << "[QNSView drawRect:]" << m_platformWindow->window() << exposedRegion; + m_platformWindow->handleExposeEvent(exposedRegion); } -- (void)viewDidChangeBackingProperties +/* + This method is called by AppKit when we are layer-backed, where + we are drawing into the layer. +*/ +- (void)displayLayer:(CALayer *)layer { - CALayer *layer = self.layer; - if (!layer) - return; + Q_ASSERT_X(self.layer && layer == self.layer, "QNSView", + "The displayLayer code path should only be hit for our own layer"); - layer.contentsScale = self.window.backingScaleFactor; + if (!m_platformWindow) + return; - // Metal layers must be manually updated on e.g. screen change - if ([layer isKindOfClass:CAMetalLayer.class]) { - [self updateMetalLayerDrawableSize:static_cast<CAMetalLayer* >(layer)]; - [self setNeedsDisplay:YES]; + if (!NSThread.isMainThread) { + // Qt is calling AppKit APIs such as -[NSOpenGLContext setView:] on secondary threads, + // which we shouldn't do. This may result in AppKit (wrongly) triggering a display on + // the thread where we made the call, so block it here and defer to the main thread. + qCWarning(lcQpaDrawing) << "Display non non-main thread! Deferring to main thread"; + dispatch_async(dispatch_get_main_queue(), ^{ self.needsDisplay = YES; }); + return; } + + qCDebug(lcQpaDrawing) << "[QNSView displayLayer]" << m_platformWindow->window(); + m_platformWindow->handleExposeEvent(QRectF::fromCGRect(self.bounds).toRect()); } @end diff --git a/src/plugins/platforms/cocoa/qnsview_gestures.mm b/src/plugins/platforms/cocoa/qnsview_gestures.mm index 61d551ee0e..a80261fd6a 100644 --- a/src/plugins/platforms/cocoa/qnsview_gestures.mm +++ b/src/plugins/platforms/cocoa/qnsview_gestures.mm @@ -43,7 +43,7 @@ Q_LOGGING_CATEGORY(lcQpaGestures, "qt.qpa.input.gestures") -@implementation QT_MANGLE_NAMESPACE(QNSView) (Gestures) +@implementation QNSView (Gestures) - (bool)handleGestureAsBeginEnd:(NSEvent *)event { @@ -70,7 +70,7 @@ Q_LOGGING_CATEGORY(lcQpaGestures, "qt.qpa.input.gestures") if ([self handleGestureAsBeginEnd:event]) return; - qCDebug(lcQpaGestures) << "magnifyWithEvent" << [event magnification] << "from device" << hex << [event deviceID]; + qCDebug(lcQpaGestures) << "magnifyWithEvent" << [event magnification] << "from device" << Qt::hex << [event deviceID]; const NSTimeInterval timestamp = [event timestamp]; QPointF windowPoint; QPointF screenPoint; @@ -85,7 +85,7 @@ Q_LOGGING_CATEGORY(lcQpaGestures, "qt.qpa.input.gestures") return; static bool zoomIn = true; - qCDebug(lcQpaGestures) << "smartMagnifyWithEvent" << zoomIn << "from device" << hex << [event deviceID]; + qCDebug(lcQpaGestures) << "smartMagnifyWithEvent" << zoomIn << "from device" << Qt::hex << [event deviceID]; const NSTimeInterval timestamp = [event timestamp]; QPointF windowPoint; QPointF screenPoint; @@ -116,7 +116,7 @@ Q_LOGGING_CATEGORY(lcQpaGestures, "qt.qpa.input.gestures") if (!m_platformWindow) return; - qCDebug(lcQpaGestures) << "swipeWithEvent" << [event deltaX] << [event deltaY] << "from device" << hex << [event deviceID]; + qCDebug(lcQpaGestures) << "swipeWithEvent" << [event deltaX] << [event deltaY] << "from device" << Qt::hex << [event deviceID]; const NSTimeInterval timestamp = [event timestamp]; QPointF windowPoint; QPointF screenPoint; @@ -145,7 +145,7 @@ Q_LOGGING_CATEGORY(lcQpaGestures, "qt.qpa.input.gestures") QPointF windowPoint; QPointF screenPoint; [self convertFromScreen:[self screenMousePoint:event] toWindowPoint:&windowPoint andScreenPoint:&screenPoint]; - qCDebug(lcQpaGestures) << "beginGestureWithEvent @" << windowPoint << "from device" << hex << [event deviceID]; + qCDebug(lcQpaGestures) << "beginGestureWithEvent @" << windowPoint << "from device" << Qt::hex << [event deviceID]; QWindowSystemInterface::handleGestureEvent(m_platformWindow->window(), QCocoaTouch::getTouchDevice(QTouchDevice::TouchPad, [event deviceID]), timestamp, Qt::BeginNativeGesture, windowPoint, screenPoint); } @@ -155,7 +155,7 @@ Q_LOGGING_CATEGORY(lcQpaGestures, "qt.qpa.input.gestures") if (!m_platformWindow) return; - qCDebug(lcQpaGestures) << "endGestureWithEvent" << "from device" << hex << [event deviceID]; + qCDebug(lcQpaGestures) << "endGestureWithEvent" << "from device" << Qt::hex << [event deviceID]; const NSTimeInterval timestamp = [event timestamp]; QPointF windowPoint; QPointF screenPoint; diff --git a/src/plugins/platforms/cocoa/qnsview_keys.mm b/src/plugins/platforms/cocoa/qnsview_keys.mm index ad751279bb..847adca207 100644 --- a/src/plugins/platforms/cocoa/qnsview_keys.mm +++ b/src/plugins/platforms/cocoa/qnsview_keys.mm @@ -39,7 +39,7 @@ // This file is included from qnsview.mm, and only used to organize the code -@implementation QT_MANGLE_NAMESPACE(QNSView) (KeysAPI) +@implementation QNSView (KeysAPI) + (Qt::KeyboardModifiers)convertKeyModifiers:(ulong)modifierFlags { @@ -60,7 +60,7 @@ @end -@implementation QT_MANGLE_NAMESPACE(QNSView) (Keys) +@implementation QNSView (Keys) - (int)convertKeyCode:(QChar)keyChar { diff --git a/src/plugins/platforms/cocoa/qnsview_menus.mm b/src/plugins/platforms/cocoa/qnsview_menus.mm index f0489552aa..a55fd97eb7 100644 --- a/src/plugins/platforms/cocoa/qnsview_menus.mm +++ b/src/plugins/platforms/cocoa/qnsview_menus.mm @@ -53,11 +53,11 @@ static bool selectorIsCutCopyPaste(SEL selector) || selector == @selector(selectAll:)); } -@interface QT_MANGLE_NAMESPACE(QNSView) (Menus) +@interface QNSView (Menus) - (void)qt_itemFired:(QCocoaNSMenuItem *)item; @end -@implementation QT_MANGLE_NAMESPACE(QNSView) (Menus) +@implementation QNSView (Menus) - (BOOL)validateMenuItem:(NSMenuItem*)item { diff --git a/src/plugins/platforms/cocoa/qnsview_mouse.mm b/src/plugins/platforms/cocoa/qnsview_mouse.mm index 3a5a074264..9e2761f850 100644 --- a/src/plugins/platforms/cocoa/qnsview_mouse.mm +++ b/src/plugins/platforms/cocoa/qnsview_mouse.mm @@ -55,7 +55,7 @@ interact with the responder chain by e.g. calling super if Qt does not accept the mouse event */ -@implementation QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper) { +@implementation QNSViewMouseMoveHelper { QNSView *view; } @@ -89,7 +89,7 @@ @end -@implementation QT_MANGLE_NAMESPACE(QNSView) (MouseAPI) +@implementation QNSView (MouseAPI) - (void)resetMouseButtons { @@ -178,7 +178,7 @@ } @end -@implementation QT_MANGLE_NAMESPACE(QNSView) (Mouse) +@implementation QNSView (Mouse) - (void)initMouse { @@ -193,7 +193,7 @@ m_dontOverrideCtrlLMB = qt_mac_resolveOption(false, m_platformWindow->window(), "_q_platform_MacDontOverrideCtrlLMB", "QT_MAC_DONT_OVERRIDE_CTRL_LMB"); - m_mouseMoveHelper = [[QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper) alloc] initWithView:self]; + m_mouseMoveHelper = [[QNSViewMouseMoveHelper alloc] initWithView:self]; NSUInteger trackingOptions = NSTrackingActiveInActiveApp | NSTrackingMouseEnteredAndExited | NSTrackingCursorUpdate; @@ -222,6 +222,11 @@ return NO; if ([self isTransparentForUserInput]) return NO; + QPointF windowPoint; + QPointF screenPoint; + [self convertFromScreen:[NSEvent mouseLocation] toWindowPoint: &windowPoint andScreenPoint: &screenPoint]; + if (!qt_window_private(m_platformWindow->window())->allowClickThrough(screenPoint.toPoint())) + return NO; return YES; } diff --git a/src/plugins/platforms/cocoa/qnsview_tablet.mm b/src/plugins/platforms/cocoa/qnsview_tablet.mm index 43b0aa0960..ba1fa55892 100644 --- a/src/plugins/platforms/cocoa/qnsview_tablet.mm +++ b/src/plugins/platforms/cocoa/qnsview_tablet.mm @@ -54,7 +54,7 @@ struct QCocoaTabletDeviceData typedef QHash<uint, QCocoaTabletDeviceData> QCocoaTabletDeviceDataHash; Q_GLOBAL_STATIC(QCocoaTabletDeviceDataHash, tabletDeviceDataHash) -@implementation QT_MANGLE_NAMESPACE(QNSView) (Tablet) +@implementation QNSView (Tablet) - (bool)handleTabletEvent:(NSEvent *)theEvent { diff --git a/src/plugins/platforms/cocoa/qnsview_touch.mm b/src/plugins/platforms/cocoa/qnsview_touch.mm index e789213f70..8dfae27c63 100644 --- a/src/plugins/platforms/cocoa/qnsview_touch.mm +++ b/src/plugins/platforms/cocoa/qnsview_touch.mm @@ -41,7 +41,7 @@ Q_LOGGING_CATEGORY(lcQpaTouch, "qt.qpa.input.touch") -@implementation QT_MANGLE_NAMESPACE(QNSView) (Touch) +@implementation QNSView (Touch) - (bool)shouldSendSingleTouch { @@ -60,7 +60,7 @@ Q_LOGGING_CATEGORY(lcQpaTouch, "qt.qpa.input.touch") const NSTimeInterval timestamp = [event timestamp]; const QList<QWindowSystemInterface::TouchPoint> points = QCocoaTouch::getCurrentTouchPointList(event, [self shouldSendSingleTouch]); - qCDebug(lcQpaTouch) << "touchesBeganWithEvent" << points << "from device" << hex << [event deviceID]; + qCDebug(lcQpaTouch) << "touchesBeganWithEvent" << points << "from device" << Qt::hex << [event deviceID]; QWindowSystemInterface::handleTouchEvent(m_platformWindow->window(), timestamp * 1000, QCocoaTouch::getTouchDevice(QTouchDevice::TouchPad, [event deviceID]), points); } @@ -71,7 +71,7 @@ Q_LOGGING_CATEGORY(lcQpaTouch, "qt.qpa.input.touch") const NSTimeInterval timestamp = [event timestamp]; const QList<QWindowSystemInterface::TouchPoint> points = QCocoaTouch::getCurrentTouchPointList(event, [self shouldSendSingleTouch]); - qCDebug(lcQpaTouch) << "touchesMovedWithEvent" << points << "from device" << hex << [event deviceID]; + qCDebug(lcQpaTouch) << "touchesMovedWithEvent" << points << "from device" << Qt::hex << [event deviceID]; QWindowSystemInterface::handleTouchEvent(m_platformWindow->window(), timestamp * 1000, QCocoaTouch::getTouchDevice(QTouchDevice::TouchPad, [event deviceID]), points); } @@ -82,7 +82,7 @@ Q_LOGGING_CATEGORY(lcQpaTouch, "qt.qpa.input.touch") const NSTimeInterval timestamp = [event timestamp]; const QList<QWindowSystemInterface::TouchPoint> points = QCocoaTouch::getCurrentTouchPointList(event, [self shouldSendSingleTouch]); - qCDebug(lcQpaTouch) << "touchesEndedWithEvent" << points << "from device" << hex << [event deviceID]; + qCDebug(lcQpaTouch) << "touchesEndedWithEvent" << points << "from device" << Qt::hex << [event deviceID]; QWindowSystemInterface::handleTouchEvent(m_platformWindow->window(), timestamp * 1000, QCocoaTouch::getTouchDevice(QTouchDevice::TouchPad, [event deviceID]), points); } @@ -93,7 +93,7 @@ Q_LOGGING_CATEGORY(lcQpaTouch, "qt.qpa.input.touch") const NSTimeInterval timestamp = [event timestamp]; const QList<QWindowSystemInterface::TouchPoint> points = QCocoaTouch::getCurrentTouchPointList(event, [self shouldSendSingleTouch]); - qCDebug(lcQpaTouch) << "touchesCancelledWithEvent" << points << "from device" << hex << [event deviceID]; + qCDebug(lcQpaTouch) << "touchesCancelledWithEvent" << points << "from device" << Qt::hex << [event deviceID]; QWindowSystemInterface::handleTouchEvent(m_platformWindow->window(), timestamp * 1000, QCocoaTouch::getTouchDevice(QTouchDevice::TouchPad, [event deviceID]), points); } diff --git a/src/plugins/platforms/cocoa/qnswindow.mm b/src/plugins/platforms/cocoa/qnswindow.mm index 68cb270457..6b4e110af2 100644 --- a/src/plugins/platforms/cocoa/qnswindow.mm +++ b/src/plugins/platforms/cocoa/qnswindow.mm @@ -255,8 +255,8 @@ static bool isMouseEvent(NSEvent *ev) - (NSColor *)backgroundColor { - return self.styleMask & NSWindowStyleMaskTexturedBackground ? - [super backgroundColor] : [NSColor clearColor]; + return self.styleMask == NSWindowStyleMaskBorderless ? + [NSColor clearColor] : [super backgroundColor]; } - (void)sendEvent:(NSEvent*)theEvent diff --git a/src/plugins/platforms/cocoa/qprintengine_mac_p.h b/src/plugins/platforms/cocoa/qprintengine_mac_p.h index 3d94227ae4..6a1ed2e263 100644 --- a/src/plugins/platforms/cocoa/qprintengine_mac_p.h +++ b/src/plugins/platforms/cocoa/qprintengine_mac_p.h @@ -64,11 +64,7 @@ #include "qpaintengine_mac_p.h" -#ifdef __OBJC__ -@class NSPrintInfo; -#else -typedef void NSPrintInfo; -#endif +Q_FORWARD_DECLARE_OBJC_CLASS(NSPrintInfo); QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/direct2d/direct2d.pro b/src/plugins/platforms/direct2d/direct2d.pro index 9764272632..6e73bd14f9 100644 --- a/src/plugins/platforms/direct2d/direct2d.pro +++ b/src/plugins/platforms/direct2d/direct2d.pro @@ -8,8 +8,8 @@ QT += \ qtConfig(accessibility): QT += accessibility_support-private qtConfig(vulkan): QT += vulkan_support-private -LIBS += -ldwmapi -lversion -lgdi32 -QMAKE_USE_PRIVATE += dwrite_1 d2d1_1 d3d11_1 dxgi1_2 +LIBS += -ldwmapi -lversion +QMAKE_USE_PRIVATE += gdi32 dwrite_1 d2d1_1 d3d11_1 dxgi1_2 include(../windows/windows.pri) diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.h b/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.h index f72ea2b038..6d4d47e3da 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.h +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.h @@ -48,7 +48,7 @@ class QWindowsDirect2DWindow; class QWindowsDirect2DBackingStore : public QPlatformBackingStore { - Q_DISABLE_COPY(QWindowsDirect2DBackingStore) + Q_DISABLE_COPY_MOVE(QWindowsDirect2DBackingStore) public: QWindowsDirect2DBackingStore(QWindow *window); diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.h b/src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.h index d8a8a49aec..8fd683106d 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.h +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.h @@ -59,7 +59,7 @@ class QColor; class QWindowsDirect2DBitmap { Q_DECLARE_PRIVATE(QWindowsDirect2DBitmap) - Q_DISABLE_COPY(QWindowsDirect2DBitmap) + Q_DISABLE_COPY_MOVE(QWindowsDirect2DBitmap) public: QWindowsDirect2DBitmap(); QWindowsDirect2DBitmap(ID2D1Bitmap1 *bitmap, ID2D1DeviceContext *dc); diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.h b/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.h index aee0eb867d..a28c674671 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.h +++ b/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.h @@ -91,7 +91,7 @@ private: }; class QWindowsDirect2DDeviceContextSuspender { - Q_DISABLE_COPY(QWindowsDirect2DDeviceContextSuspender) + Q_DISABLE_COPY_MOVE(QWindowsDirect2DDeviceContextSuspender) QWindowsDirect2DDeviceContext *m_dc; public: diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp index 86c863ec50..e074f87eb4 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp @@ -51,22 +51,11 @@ #include <QtCore/qversionnumber.h> #include <QtGui/private/qpixmap_raster_p.h> #include <QtGui/qpa/qwindowsysteminterface.h> -#include <QtEventDispatcherSupport/private/qwindowsguieventdispatcher_p.h> #include <QVarLengthArray> QT_BEGIN_NAMESPACE -class QWindowsDirect2DEventDispatcher : public QWindowsGuiEventDispatcher -{ -public: - QWindowsDirect2DEventDispatcher(QObject *parent = nullptr) - : QWindowsGuiEventDispatcher(parent) - { - uninstallMessageHook(); // ### Workaround for QTBUG-42428 - } -}; - class QWindowsDirect2DIntegrationPrivate { public: @@ -91,7 +80,7 @@ static QVersionNumber systemD2DVersion() if (VerQueryValue(info.constData(), __TEXT("\\"), reinterpret_cast<void **>(&fi), &size) && size) { - const VS_FIXEDFILEINFO *verInfo = reinterpret_cast<const VS_FIXEDFILEINFO *>(fi); + const auto *verInfo = reinterpret_cast<const VS_FIXEDFILEINFO *>(fi); return QVersionNumber{HIWORD(verInfo->dwFileVersionMS), LOWORD(verInfo->dwFileVersionMS), HIWORD(verInfo->dwFileVersionLS), LOWORD(verInfo->dwFileVersionLS)}; } @@ -140,7 +129,7 @@ QWindowsDirect2DIntegration *QWindowsDirect2DIntegration::create(const QStringLi return nullptr; } - QWindowsDirect2DIntegration *integration = new QWindowsDirect2DIntegration(paramList); + auto *integration = new QWindowsDirect2DIntegration(paramList); if (!integration->init()) { delete integration; @@ -188,11 +177,6 @@ QPlatformBackingStore *QWindowsDirect2DIntegration::createPlatformBackingStore(Q return new QWindowsDirect2DBackingStore(window); } -QAbstractEventDispatcher *QWindowsDirect2DIntegration::createEventDispatcher() const -{ - return new QWindowsDirect2DEventDispatcher; -} - QWindowsDirect2DContext *QWindowsDirect2DIntegration::direct2DContext() const { return &d->m_d2dContext; diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.h b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.h index 19c7521eb7..5ea36e04bc 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.h +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.h @@ -61,7 +61,6 @@ public: QPlatformNativeInterface *nativeInterface() const override; QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const override; QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const override; - QAbstractEventDispatcher *createEventDispatcher() const override; QWindowsDirect2DContext *direct2DContext() const; diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp index fa201c784e..03be44e095 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp @@ -253,7 +253,7 @@ struct D2DVectorPathCache { static void cleanup_func(QPaintEngineEx *engine, void *data) { Q_UNUSED(engine); - D2DVectorPathCache *e = static_cast<D2DVectorPathCache *>(data); + auto *e = static_cast<D2DVectorPathCache *>(data); delete e; } }; @@ -689,7 +689,7 @@ public: *needsEmulation = true; } else { ComPtr<ID2D1LinearGradientBrush> linear; - const QLinearGradient *qlinear = static_cast<const QLinearGradient *>(newBrush.gradient()); + const auto *qlinear = static_cast<const QLinearGradient *>(newBrush.gradient()); D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES linearGradientBrushProperties; ComPtr<ID2D1GradientStopCollection> gradientStopCollection; @@ -727,7 +727,7 @@ public: *needsEmulation = true; } else { ComPtr<ID2D1RadialGradientBrush> radial; - const QRadialGradient *qradial = static_cast<const QRadialGradient *>(newBrush.gradient()); + const auto *qradial = static_cast<const QRadialGradient *>(newBrush.gradient()); D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES radialGradientBrushProperties; ComPtr<ID2D1GradientStopCollection> gradientStopCollection; @@ -807,7 +807,7 @@ public: : nullptr; if (cacheEntry) { - D2DVectorPathCache *e = static_cast<D2DVectorPathCache *>(cacheEntry->data); + auto *e = static_cast<D2DVectorPathCache *>(cacheEntry->data); if (alias && e->aliased) return e->aliased; else if (!alias && e->antiAliased) @@ -885,7 +885,7 @@ public: if (!cacheEntry) cacheEntry = path.addCacheData(q, new D2DVectorPathCache, D2DVectorPathCache::cleanup_func); - D2DVectorPathCache *e = static_cast<D2DVectorPathCache *>(cacheEntry->data); + auto *e = static_cast<D2DVectorPathCache *>(cacheEntry->data); if (alias) e->aliased = geometry; else @@ -941,9 +941,16 @@ public: { Q_Q(QWindowsDirect2DPaintEngine); +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED // Default path (no optimization) if (!(path.shape() == QVectorPath::LinesHint || path.shape() == QVectorPath::PolygonHint) - || !pen.dashBrush || q->state()->renderHints.testFlag(QPainter::HighQualityAntialiasing)) { + || !pen.dashBrush +#if QT_DEPRECATED_SINCE(5, 14) + || q->state()->renderHints.testFlag(QPainter::HighQualityAntialiasing) +#endif + || q->state()->renderHints.testFlag(QPainter::Antialiasing)) { +QT_WARNING_POP ComPtr<ID2D1Geometry> geometry = vectorPathToID2D1PathGeometry(path); if (!geometry) { qWarning("%s: Could not convert path to d2d geometry", __FUNCTION__); @@ -1481,7 +1488,7 @@ void QWindowsDirect2DPaintEngine::drawPixmap(const QRectF &r, return; } - QWindowsDirect2DPlatformPixmap *pp = static_cast<QWindowsDirect2DPlatformPixmap *>(pm.handle()); + auto *pp = static_cast<QWindowsDirect2DPlatformPixmap *>(pm.handle()); QWindowsDirect2DBitmap *bitmap = pp->bitmap(); ensurePen(); @@ -1593,7 +1600,7 @@ void QWindowsDirect2DPaintEngine::drawTextItem(const QPointF &p, const QTextItem Q_D(QWindowsDirect2DPaintEngine); D2D_TAG(D2DDebugDrawTextItemTag); - const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem); + const auto &ti = static_cast<const QTextItemInt &>(textItem); if (ti.glyphs.numGlyphs == 0) return; @@ -1686,7 +1693,7 @@ void QWindowsDirect2DPaintEngine::rasterFill(const QVectorPath &path, const QBru p.setBrush(state()->brush); p.setPen(state()->pen); - QPaintEngineEx *extended = static_cast<QPaintEngineEx *>(engine); + auto *extended = static_cast<QPaintEngineEx *>(engine); for (const QPainterClipInfo &info : qAsConst(state()->clipInfo)) { extended->state()->matrix = info.matrix; extended->transformChanged(); @@ -1800,7 +1807,7 @@ void QWindowsDirect2DPaintEngine::resume() class QWindowsDirect2DPaintEngineSuspenderImpl { - Q_DISABLE_COPY(QWindowsDirect2DPaintEngineSuspenderImpl) + Q_DISABLE_COPY_MOVE(QWindowsDirect2DPaintEngineSuspenderImpl) QWindowsDirect2DPaintEngine *m_engine; bool m_active; public: diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h index 6404c60b13..f61e908bce 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h @@ -128,7 +128,7 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(QWindowsDirect2DPaintEngine::Flags) class QWindowsDirect2DPaintEngineSuspenderPrivate; class QWindowsDirect2DPaintEngineSuspender { - Q_DISABLE_COPY(QWindowsDirect2DPaintEngineSuspender) + Q_DISABLE_COPY_MOVE(QWindowsDirect2DPaintEngineSuspender) Q_DECLARE_PRIVATE(QWindowsDirect2DPaintEngineSuspender) QScopedPointer<QWindowsDirect2DPaintEngineSuspenderPrivate> d_ptr; public: diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp index 239e5f3087..c417daaeae 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp @@ -310,7 +310,7 @@ void QWindowsDirect2DWindow::setupBitmap() QWindowsDirect2DPaintEngine::Flags flags = QWindowsDirect2DPaintEngine::NoFlag; if (!m_directRendering) flags |= QWindowsDirect2DPaintEngine::TranslucentTopLevelWindow; - QWindowsDirect2DPlatformPixmap *pp = new QWindowsDirect2DPlatformPixmap(QPlatformPixmap::PixmapType, + auto *pp = new QWindowsDirect2DPlatformPixmap(QPlatformPixmap::PixmapType, flags, m_bitmap.data()); m_pixmap.reset(new QPixmap(pp)); diff --git a/src/plugins/platforms/eglfs/api/qeglfscursor_p.h b/src/plugins/platforms/eglfs/api/qeglfscursor_p.h index 89c2e89f58..8768f9dd8c 100644 --- a/src/plugins/platforms/eglfs/api/qeglfscursor_p.h +++ b/src/plugins/platforms/eglfs/api/qeglfscursor_p.h @@ -59,6 +59,8 @@ #include <QtGui/QOpenGLShaderProgram> #include <QtGui/private/qinputdevicemanager_p.h> +#include <QtCore/qvector.h> + QT_BEGIN_NAMESPACE class QOpenGLShaderProgram; @@ -143,7 +145,7 @@ private: int cursorsPerRow; int width, height; // width and height of the atlas int cursorWidth, cursorHeight; // width and height of cursors inside the atlas - QList<QPoint> hotSpots; + QVector<QPoint> hotSpots; QImage image; // valid until it's uploaded } m_cursorAtlas; diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.h index c96dd585d3..d47b579238 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.h @@ -41,7 +41,7 @@ #define QEGLFSKMSGBMCURSOR_H #include <qpa/qplatformcursor.h> -#include <QtCore/QList> +#include <QtCore/QVector> #include <QtGui/QImage> #include <QtGui/private/qinputdevicemanager_p.h> @@ -110,7 +110,7 @@ private: int cursorsPerRow; int width, height; // width and height of the atlas int cursorWidth, cursorHeight; // width and height of cursors inside the atlas - QList<QPoint> hotSpots; + QVector<QPoint> hotSpots; QImage image; } m_cursorAtlas; }; diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp index 359b086372..16dbfe1522 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp @@ -161,7 +161,7 @@ gbm_surface *QEglFSKmsGbmScreen::createSurface(EGLConfig eglConfig) if (queryFromEgl) { EGLint native_format = -1; EGLBoolean success = eglGetConfigAttrib(display(), eglConfig, EGL_NATIVE_VISUAL_ID, &native_format); - qCDebug(qLcEglfsKmsDebug) << "Got native format" << hex << native_format << dec + qCDebug(qLcEglfsKmsDebug) << "Got native format" << Qt::hex << native_format << Qt::dec << "from eglGetConfigAttrib() with return code" << bool(success); if (success) { @@ -344,6 +344,9 @@ void QEglFSKmsGbmScreen::flip() static int zpos = qEnvironmentVariableIntValue("QT_QPA_EGLFS_KMS_ZPOS"); if (zpos) drmModeAtomicAddProperty(request, op.eglfs_plane->id, op.eglfs_plane->zposPropertyId, zpos); + static uint blendOp = uint(qEnvironmentVariableIntValue("QT_QPA_EGLFS_KMS_BLEND_OP")); + if (blendOp) + drmModeAtomicAddProperty(request, op.eglfs_plane->id, op.eglfs_plane->blendOpPropertyId, blendOp); } #endif } else { diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.cpp index 2e84915c80..07b2de7c58 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.cpp @@ -66,7 +66,7 @@ QAtomicInt running; void EventReader::run() { xcb_generic_event_t *event = nullptr; - while (running.load() && (event = xcb_wait_for_event(m_integration->connection()))) { + while (running.loadRelaxed() && (event = xcb_wait_for_event(m_integration->connection()))) { uint response_type = event->response_type & ~0x80; switch (response_type) { case XCB_CLIENT_MESSAGE: { diff --git a/src/plugins/platforms/haiku/qhaikuapplication.cpp b/src/plugins/platforms/haiku/qhaikuapplication.cpp index b75810c453..de4acdfd4a 100644 --- a/src/plugins/platforms/haiku/qhaikuapplication.cpp +++ b/src/plugins/platforms/haiku/qhaikuapplication.cpp @@ -42,6 +42,8 @@ #include <QCoreApplication> #include <QFileOpenEvent> +#include <qpa/qwindowsysteminterface.h> + #include <Entry.h> #include <Path.h> @@ -52,8 +54,7 @@ QHaikuApplication::QHaikuApplication(const char *signature) bool QHaikuApplication::QuitRequested() { - QEvent quitEvent(QEvent::Quit); - QCoreApplication::sendEvent(QCoreApplication::instance(), &quitEvent); + QWindowSystemInterface::handleApplicationTermination<QWindowSystemInterface::SynchronousDelivery>(); return true; } diff --git a/src/plugins/platforms/ios/qioscontext.mm b/src/plugins/platforms/ios/qioscontext.mm index 535e7d7aa6..c9509ae599 100644 --- a/src/plugins/platforms/ios/qioscontext.mm +++ b/src/plugins/platforms/ios/qioscontext.mm @@ -118,7 +118,7 @@ QSurfaceFormat QIOSContext::format() const return m_format; } -#define QT_IOS_GL_STATUS_CASE(val) case val: return QLatin1Literal(#val) +#define QT_IOS_GL_STATUS_CASE(val) case val: return QLatin1String(#val) static QString fboStatusString(GLenum status) { diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm index 776343c5aa..c5856051de 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.mm +++ b/src/plugins/platforms/ios/qioseventdispatcher.mm @@ -211,6 +211,8 @@ namespace } logActivity; } +using namespace QT_PREPEND_NAMESPACE(QtPrivate); + extern "C" int qt_main_wrapper(int argc, char *argv[]) { @autoreleasepool { diff --git a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp index dc7ea08dc5..cb8962d4b8 100644 --- a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp +++ b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp @@ -188,7 +188,7 @@ static QImage::Format determineFormat(const fb_var_screeninfo &info, int depth) if (memcmp(rgba, rgb888, 3 * sizeof(fb_bitfield)) == 0) { format = QImage::Format_RGB888; } else if (memcmp(rgba, bgr888, 3 * sizeof(fb_bitfield)) == 0) { - format = QImage::Format_RGB888; + format = QImage::Format_BGR888; // pixeltype = BGRPixel; } break; diff --git a/src/plugins/platforms/mirclient/mirclient.json b/src/plugins/platforms/mirclient/mirclient.json deleted file mode 100644 index c31558a2f1..0000000000 --- a/src/plugins/platforms/mirclient/mirclient.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "Keys": [ "mirclient" ] -} diff --git a/src/plugins/platforms/mirclient/mirclient.pro b/src/plugins/platforms/mirclient/mirclient.pro deleted file mode 100644 index d9eb069200..0000000000 --- a/src/plugins/platforms/mirclient/mirclient.pro +++ /dev/null @@ -1,61 +0,0 @@ -TARGET = qmirclient - -QT += \ - core-private gui-private dbus \ - theme_support-private eventdispatcher_support-private \ - fontdatabase_support-private egl_support-private - -qtHaveModule(linuxaccessibility_support-private): \ - QT += linuxaccessibility_support-private - -DEFINES += MESA_EGL_NO_X11_HEADERS -# CONFIG += c++11 # only enables C++0x -QMAKE_CXXFLAGS += -fvisibility=hidden -fvisibility-inlines-hidden -std=c++11 -Werror -Wall -QMAKE_LFLAGS += -std=c++11 -Wl,-no-undefined - -QMAKE_USE_PRIVATE += mirclient - -SOURCES = \ - qmirclientappstatecontroller.cpp \ - qmirclientbackingstore.cpp \ - qmirclientclipboard.cpp \ - qmirclientcursor.cpp \ - qmirclientdebugextension.cpp \ - qmirclientdesktopwindow.cpp \ - qmirclientglcontext.cpp \ - qmirclientinput.cpp \ - qmirclientintegration.cpp \ - qmirclientnativeinterface.cpp \ - qmirclientplatformservices.cpp \ - qmirclientplugin.cpp \ - qmirclientscreen.cpp \ - qmirclientscreenobserver.cpp \ - qmirclienttheme.cpp \ - qmirclientwindow.cpp - -HEADERS = \ - qmirclientappstatecontroller.h \ - qmirclientbackingstore.h \ - qmirclientclipboard.h \ - qmirclientcursor.h \ - qmirclientdebugextension.h \ - qmirclientdesktopwindow.h \ - qmirclientglcontext.h \ - qmirclientinput.h \ - qmirclientintegration.h \ - qmirclientlogging.h \ - qmirclientnativeinterface.h \ - qmirclientorientationchangeevent_p.h \ - qmirclientplatformservices.h \ - qmirclientplugin.h \ - qmirclientscreen.h \ - qmirclientscreenobserver.h \ - qmirclienttheme.h \ - qmirclientwindow.h - -QMAKE_USE_PRIVATE += xkbcommon - -PLUGIN_TYPE = platforms -PLUGIN_CLASS_NAME = MirServerIntegrationPlugin -!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - -load(qt_plugin) diff --git a/src/plugins/platforms/mirclient/qmirclientappstatecontroller.cpp b/src/plugins/platforms/mirclient/qmirclientappstatecontroller.cpp deleted file mode 100644 index 69fc9b7aa7..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientappstatecontroller.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#include "qmirclientappstatecontroller.h" - -#include <qpa/qwindowsysteminterface.h> - -/* - * QMirClientAppStateController - updates Qt's QApplication::applicationState property. - * - * Tries to avoid active-inactive-active invocations using a timer. The rapid state - * change can confuse some applications. - */ - -QMirClientAppStateController::QMirClientAppStateController() - : m_suspended(false) - , m_lastActive(true) -{ - m_inactiveTimer.setSingleShot(true); - m_inactiveTimer.setInterval(10); - QObject::connect(&m_inactiveTimer, &QTimer::timeout, []() - { - QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationInactive); - }); -} - -void QMirClientAppStateController::setSuspended() -{ - m_inactiveTimer.stop(); - if (!m_suspended) { - m_suspended = true; - - QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationSuspended); - } -} - -void QMirClientAppStateController::setResumed() -{ - m_inactiveTimer.stop(); - if (m_suspended) { - m_suspended = false; - - if (m_lastActive) { - QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationActive); - } else { - QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationInactive); - } - } -} - -void QMirClientAppStateController::setWindowFocused(bool focused) -{ - if (m_suspended) { - return; - } - - if (focused) { - m_inactiveTimer.stop(); - QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationActive); - } else { - m_inactiveTimer.start(); - } - - m_lastActive = focused; -} diff --git a/src/plugins/platforms/mirclient/qmirclientappstatecontroller.h b/src/plugins/platforms/mirclient/qmirclientappstatecontroller.h deleted file mode 100644 index b3aa0022d9..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientappstatecontroller.h +++ /dev/null @@ -1,62 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef QMIRCLIENTAPPSTATECONTROLLER_H -#define QMIRCLIENTAPPSTATECONTROLLER_H - -#include <QTimer> - -class QMirClientAppStateController -{ -public: - QMirClientAppStateController(); - - void setSuspended(); - void setResumed(); - - void setWindowFocused(bool focused); - -private: - bool m_suspended; - bool m_lastActive; - QTimer m_inactiveTimer; -}; - -#endif // QMIRCLIENTAPPSTATECONTROLLER_H diff --git a/src/plugins/platforms/mirclient/qmirclientbackingstore.cpp b/src/plugins/platforms/mirclient/qmirclientbackingstore.cpp deleted file mode 100644 index 51363619d9..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientbackingstore.cpp +++ /dev/null @@ -1,157 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#include "qmirclientbackingstore.h" -#include "qmirclientlogging.h" -#include <QtGui/QOpenGLContext> -#include <QtGui/QOpenGLTexture> -#include <QtGui/QMatrix4x4> -#include <QtGui/qopengltextureblitter.h> -#include <QtGui/qopenglfunctions.h> - -QMirClientBackingStore::QMirClientBackingStore(QWindow* window) - : QPlatformBackingStore(window) - , mContext(new QOpenGLContext) - , mTexture(new QOpenGLTexture(QOpenGLTexture::Target2D)) - , mBlitter(new QOpenGLTextureBlitter) -{ - mContext->setFormat(window->requestedFormat()); - mContext->setScreen(window->screen()); - mContext->create(); - - window->setSurfaceType(QSurface::OpenGLSurface); -} - -QMirClientBackingStore::~QMirClientBackingStore() -{ - mContext->makeCurrent(window()); // needed as QOpenGLTexture destructor assumes current context -} - -void QMirClientBackingStore::flush(QWindow* window, const QRegion& region, const QPoint& offset) -{ - Q_UNUSED(region); - Q_UNUSED(offset); - mContext->makeCurrent(window); - glViewport(0, 0, window->width(), window->height()); - - updateTexture(); - - if (!mBlitter->isCreated()) - mBlitter->create(); - - mBlitter->bind(); - mBlitter->blit(mTexture->textureId(), QMatrix4x4(), QOpenGLTextureBlitter::OriginTopLeft); - mBlitter->release(); - - mContext->swapBuffers(window); -} - -void QMirClientBackingStore::updateTexture() -{ - if (mDirty.isNull()) - return; - - if (!mTexture->isCreated()) { - mTexture->setMinificationFilter(QOpenGLTexture::Nearest); - mTexture->setMagnificationFilter(QOpenGLTexture::Nearest); - mTexture->setWrapMode(QOpenGLTexture::ClampToEdge); - mTexture->setData(mImage, QOpenGLTexture::DontGenerateMipMaps); - mTexture->create(); - } - mTexture->bind(); - - QRegion fixed; - QRect imageRect = mImage.rect(); - - for (const QRect &rect : mDirty) { - // intersect with image rect to be sure - QRect r = imageRect & rect; - - // if the rect is wide enough it is cheaper to just extend it instead of doing an image copy - if (r.width() >= imageRect.width() / 2) { - r.setX(0); - r.setWidth(imageRect.width()); - } - - fixed |= r; - } - - for (const QRect &rect : fixed) { - // if the sub-rect is full-width we can pass the image data directly to - // OpenGL instead of copying, since there is no gap between scanlines - if (rect.width() == imageRect.width()) { - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE, - mImage.constScanLine(rect.y())); - } else { - glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE, - mImage.copy(rect).constBits()); - } - } - /* End of code taken from QEGLPlatformBackingStore */ - - mDirty = QRegion(); -} - - -void QMirClientBackingStore::beginPaint(const QRegion& region) -{ - mDirty |= region; -} - -void QMirClientBackingStore::resize(const QSize& size, const QRegion& /*staticContents*/) -{ - mImage = QImage(size, QImage::Format_RGBA8888); - - mContext->makeCurrent(window()); - - if (mTexture->isCreated()) - mTexture->destroy(); -} - -QPaintDevice* QMirClientBackingStore::paintDevice() -{ - return &mImage; -} - -QImage QMirClientBackingStore::toImage() const -{ - // used by QPlatformBackingStore::composeAndFlush - return mImage; -} diff --git a/src/plugins/platforms/mirclient/qmirclientbackingstore.h b/src/plugins/platforms/mirclient/qmirclientbackingstore.h deleted file mode 100644 index 7644c77df2..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientbackingstore.h +++ /dev/null @@ -1,74 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef QMIRCLIENTBACKINGSTORE_H -#define QMIRCLIENTBACKINGSTORE_H - -#include <qpa/qplatformbackingstore.h> - -class QOpenGLContext; -class QOpenGLTexture; -class QOpenGLTextureBlitter; - -class QMirClientBackingStore : public QPlatformBackingStore -{ -public: - QMirClientBackingStore(QWindow* window); - virtual ~QMirClientBackingStore(); - - // QPlatformBackingStore methods. - void beginPaint(const QRegion&) override; - void flush(QWindow* window, const QRegion& region, const QPoint& offset) override; - void resize(const QSize& size, const QRegion& staticContents) override; - QPaintDevice* paintDevice() override; - QImage toImage() const override; - -protected: - void updateTexture(); - -private: - QScopedPointer<QOpenGLContext> mContext; - QScopedPointer<QOpenGLTexture> mTexture; - QScopedPointer<QOpenGLTextureBlitter> mBlitter; - QImage mImage; - QRegion mDirty; -}; - -#endif // QMIRCLIENTBACKINGSTORE_H diff --git a/src/plugins/platforms/mirclient/qmirclientclipboard.cpp b/src/plugins/platforms/mirclient/qmirclientclipboard.cpp deleted file mode 100644 index b9fc9b3b42..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientclipboard.cpp +++ /dev/null @@ -1,181 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#include "qmirclientclipboard.h" -#include "qmirclientlogging.h" -#include "qmirclientwindow.h" - -#include <QDBusPendingCallWatcher> -#include <QGuiApplication> -#include <QSignalBlocker> -#include <QtCore/QMimeData> -#include <QtCore/QStringList> - -// content-hub -#include <com/ubuntu/content/hub.h> - -// get this cumbersome nested namespace out of the way -using namespace com::ubuntu::content; - -QMirClientClipboard::QMirClientClipboard() - : mMimeData(new QMimeData) - , mContentHub(Hub::Client::instance()) -{ - connect(mContentHub, &Hub::pasteboardChanged, this, [this]() { - if (mClipboardState == QMirClientClipboard::SyncedClipboard) { - mClipboardState = QMirClientClipboard::OutdatedClipboard; - emitChanged(QClipboard::Clipboard); - } - }); - - connect(qGuiApp, &QGuiApplication::applicationStateChanged, - this, &QMirClientClipboard::onApplicationStateChanged); - - requestMimeData(); -} - -QMirClientClipboard::~QMirClientClipboard() -{ - delete mMimeData; -} - -QMimeData* QMirClientClipboard::mimeData(QClipboard::Mode mode) -{ - if (mode != QClipboard::Clipboard) - return nullptr; - - // Blocks dataChanged() signal from being emitted. Makes no sense to emit it from - // inside the data getter. - const QSignalBlocker blocker(this); - - if (mClipboardState == OutdatedClipboard) { - updateMimeData(); - } else if (mClipboardState == SyncingClipboard) { - mPasteReply->waitForFinished(); - } - - return mMimeData; -} - -void QMirClientClipboard::setMimeData(QMimeData* mimeData, QClipboard::Mode mode) -{ - QWindow *focusWindow = QGuiApplication::focusWindow(); - if (focusWindow && mode == QClipboard::Clipboard && mimeData != nullptr) { - QString surfaceId = static_cast<QMirClientWindow*>(focusWindow->handle())->persistentSurfaceId(); - - QDBusPendingCall reply = mContentHub->createPaste(surfaceId, *mimeData); - - // Don't care whether it succeeded - QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this); - connect(watcher, &QDBusPendingCallWatcher::finished, - watcher, &QObject::deleteLater); - - mMimeData = mimeData; - mClipboardState = SyncedClipboard; - emitChanged(QClipboard::Clipboard); - } -} - -bool QMirClientClipboard::supportsMode(QClipboard::Mode mode) const -{ - return mode == QClipboard::Clipboard; -} - -bool QMirClientClipboard::ownsMode(QClipboard::Mode mode) const -{ - Q_UNUSED(mode); - return false; -} - -void QMirClientClipboard::onApplicationStateChanged(Qt::ApplicationState state) -{ - if (state == Qt::ApplicationActive) { - // Only focused or active applications might be allowed to paste, so we probably - // missed changes in the clipboard while we were hidden, inactive or, more importantly, - // suspended. - requestMimeData(); - } -} - -void QMirClientClipboard::updateMimeData() -{ - if (qGuiApp->applicationState() != Qt::ApplicationActive) { - // Don't even bother asking as content-hub would probably ignore our request (and should). - return; - } - - delete mMimeData; - - QWindow *focusWindow = QGuiApplication::focusWindow(); - if (focusWindow) { - QString surfaceId = static_cast<QMirClientWindow*>(focusWindow->handle())->persistentSurfaceId(); - mMimeData = mContentHub->latestPaste(surfaceId); - mClipboardState = SyncedClipboard; - emitChanged(QClipboard::Clipboard); - } -} - -void QMirClientClipboard::requestMimeData() -{ - if (qGuiApp->applicationState() != Qt::ApplicationActive) { - // Don't even bother asking as content-hub would probably ignore our request (and should). - return; - } - - QWindow *focusWindow = QGuiApplication::focusWindow(); - if (!focusWindow) { - return; - } - - QString surfaceId = static_cast<QMirClientWindow*>(focusWindow->handle())->persistentSurfaceId(); - QDBusPendingCall reply = mContentHub->requestLatestPaste(surfaceId); - mClipboardState = SyncingClipboard; - - mPasteReply = new QDBusPendingCallWatcher(reply, this); - connect(mPasteReply, &QDBusPendingCallWatcher::finished, - this, [this]() { - delete mMimeData; - mMimeData = mContentHub->paste(*mPasteReply); - mClipboardState = SyncedClipboard; - mPasteReply->deleteLater(); - mPasteReply = nullptr; - emitChanged(QClipboard::Clipboard); - }); -} diff --git a/src/plugins/platforms/mirclient/qmirclientclipboard.h b/src/plugins/platforms/mirclient/qmirclientclipboard.h deleted file mode 100644 index 09e9bcdf38..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientclipboard.h +++ /dev/null @@ -1,92 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef QMIRCLIENTCLIPBOARD_H -#define QMIRCLIENTCLIPBOARD_H - -#include <qpa/qplatformclipboard.h> - -#include <QMimeData> -#include <QPointer> - -namespace com { - namespace ubuntu { - namespace content { - class Hub; - } - } -} - -class QDBusPendingCallWatcher; - -class QMirClientClipboard : public QObject, public QPlatformClipboard -{ - Q_OBJECT -public: - QMirClientClipboard(); - virtual ~QMirClientClipboard(); - - // QPlatformClipboard methods. - QMimeData* mimeData(QClipboard::Mode mode = QClipboard::Clipboard) override; - void setMimeData(QMimeData* data, QClipboard::Mode mode = QClipboard::Clipboard) override; - bool supportsMode(QClipboard::Mode mode) const override; - bool ownsMode(QClipboard::Mode mode) const override; - -private Q_SLOTS: - void onApplicationStateChanged(Qt::ApplicationState state); - -private: - void updateMimeData(); - void requestMimeData(); - - QMimeData *mMimeData; - - enum { - OutdatedClipboard, // Our mimeData is outdated, need to fetch latest from ContentHub - SyncingClipboard, // Our mimeData is outdated and we are waiting for ContentHub to reply with the latest paste - SyncedClipboard // Our mimeData is in sync with what ContentHub has - } mClipboardState{OutdatedClipboard}; - - com::ubuntu::content::Hub *mContentHub; - - QDBusPendingCallWatcher *mPasteReply{nullptr}; -}; - -#endif // QMIRCLIENTCLIPBOARD_H diff --git a/src/plugins/platforms/mirclient/qmirclientcursor.cpp b/src/plugins/platforms/mirclient/qmirclientcursor.cpp deleted file mode 100644 index 812cde95c6..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientcursor.cpp +++ /dev/null @@ -1,209 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015-2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#include "qmirclientcursor.h" - -#include "qmirclientlogging.h" -#include "qmirclientwindow.h" - -#include <mir_toolkit/mir_client_library.h> - -Q_LOGGING_CATEGORY(mirclientCursor, "qt.qpa.mirclient.cursor", QtWarningMsg) - -QMirClientCursor::QMirClientCursor(MirConnection *connection) - : mConnection(connection) -{ - /* - * TODO: Add the missing cursors to Mir (LP: #1388987) - * Those are the ones without a mir_ prefix, which are X11 cursors - * and won't be understood by any shell other than Unity8. - */ - mShapeToCursorName[Qt::ArrowCursor] = mir_arrow_cursor_name; - mShapeToCursorName[Qt::UpArrowCursor] = "up_arrow"; - mShapeToCursorName[Qt::CrossCursor] = mir_crosshair_cursor_name; - mShapeToCursorName[Qt::WaitCursor] = mir_busy_cursor_name; - mShapeToCursorName[Qt::IBeamCursor] = mir_caret_cursor_name; - mShapeToCursorName[Qt::SizeVerCursor] = mir_vertical_resize_cursor_name; - mShapeToCursorName[Qt::SizeHorCursor] = mir_horizontal_resize_cursor_name; - mShapeToCursorName[Qt::SizeBDiagCursor] = mir_diagonal_resize_bottom_to_top_cursor_name; - mShapeToCursorName[Qt::SizeFDiagCursor] = mir_diagonal_resize_top_to_bottom_cursor_name; - mShapeToCursorName[Qt::SizeAllCursor] = mir_omnidirectional_resize_cursor_name; - mShapeToCursorName[Qt::BlankCursor] = mir_disabled_cursor_name; - mShapeToCursorName[Qt::SplitVCursor] = mir_vsplit_resize_cursor_name; - mShapeToCursorName[Qt::SplitHCursor] = mir_hsplit_resize_cursor_name; - mShapeToCursorName[Qt::PointingHandCursor] = mir_pointing_hand_cursor_name; - mShapeToCursorName[Qt::ForbiddenCursor] = "forbidden"; - mShapeToCursorName[Qt::WhatsThisCursor] = "whats_this"; - mShapeToCursorName[Qt::BusyCursor] = "left_ptr_watch"; - mShapeToCursorName[Qt::OpenHandCursor] = mir_open_hand_cursor_name; - mShapeToCursorName[Qt::ClosedHandCursor] = mir_closed_hand_cursor_name; - mShapeToCursorName[Qt::DragCopyCursor] = "dnd-copy"; - mShapeToCursorName[Qt::DragMoveCursor] = "dnd-move"; - mShapeToCursorName[Qt::DragLinkCursor] = "dnd-link"; -} - -namespace { -const char *qtCursorShapeToStr(Qt::CursorShape shape) -{ - switch (shape) { - case Qt::ArrowCursor: - return "Arrow"; - case Qt::UpArrowCursor: - return "UpArrow"; - case Qt::CrossCursor: - return "Cross"; - case Qt::WaitCursor: - return "Wait"; - case Qt::IBeamCursor: - return "IBeam"; - case Qt::SizeVerCursor: - return "SizeVer"; - case Qt::SizeHorCursor: - return "SizeHor"; - case Qt::SizeBDiagCursor: - return "SizeBDiag"; - case Qt::SizeFDiagCursor: - return "SizeFDiag"; - case Qt::SizeAllCursor: - return "SizeAll"; - case Qt::BlankCursor: - return "Blank"; - case Qt::SplitVCursor: - return "SplitV"; - case Qt::SplitHCursor: - return "SplitH"; - case Qt::PointingHandCursor: - return "PointingHand"; - case Qt::ForbiddenCursor: - return "Forbidden"; - case Qt::WhatsThisCursor: - return "WhatsThis"; - case Qt::BusyCursor: - return "Busy"; - case Qt::OpenHandCursor: - return "OpenHand"; - case Qt::ClosedHandCursor: - return "ClosedHand"; - case Qt::DragCopyCursor: - return "DragCopy"; - case Qt::DragMoveCursor: - return "DragMove"; - case Qt::DragLinkCursor: - return "DragLink"; - case Qt::BitmapCursor: - return "Bitmap"; - default: - return "???"; - } -} -} // anonymous namespace - -void QMirClientCursor::changeCursor(QCursor *windowCursor, QWindow *window) -{ - if (!window) { - return; - } - - MirSurface *surface = static_cast<QMirClientWindow*>(window->handle())->mirSurface(); - - if (!surface) { - return; - } - - - if (windowCursor) { - qCDebug(mirclientCursor, "changeCursor shape=%s, window=%p", qtCursorShapeToStr(windowCursor->shape()), window); - if (!windowCursor->pixmap().isNull()) { - configureMirCursorWithPixmapQCursor(surface, *windowCursor); - } else if (windowCursor->shape() == Qt::BitmapCursor) { - // TODO: Implement bitmap cursor support - applyDefaultCursorConfiguration(surface); - } else { - const auto &cursorName = mShapeToCursorName.value(windowCursor->shape(), QByteArray("left_ptr")); - auto cursorConfiguration = mir_cursor_configuration_from_name(cursorName.data()); - mir_surface_configure_cursor(surface, cursorConfiguration); - mir_cursor_configuration_destroy(cursorConfiguration); - } - } else { - applyDefaultCursorConfiguration(surface); - } - -} - -void QMirClientCursor::configureMirCursorWithPixmapQCursor(MirSurface *surface, QCursor &cursor) -{ - QImage image = cursor.pixmap().toImage(); - - if (image.format() != QImage::Format_ARGB32) { - image = image.convertToFormat(QImage::Format_ARGB32); - } - - MirBufferStream *bufferStream = mir_connection_create_buffer_stream_sync(mConnection, - image.width(), image.height(), mir_pixel_format_argb_8888, mir_buffer_usage_software); - - { - MirGraphicsRegion region; - mir_buffer_stream_get_graphics_region(bufferStream, ®ion); - - char *regionLine = region.vaddr; - Q_ASSERT(image.bytesPerLine() <= region.stride); - for (int i = 0; i < image.height(); ++i) { - memcpy(regionLine, image.scanLine(i), image.bytesPerLine()); - regionLine += region.stride; - } - } - - mir_buffer_stream_swap_buffers_sync(bufferStream); - - { - auto configuration = mir_cursor_configuration_from_buffer_stream(bufferStream, cursor.hotSpot().x(), cursor.hotSpot().y()); - mir_surface_configure_cursor(surface, configuration); - mir_cursor_configuration_destroy(configuration); - } - - mir_buffer_stream_release_sync(bufferStream); -} - -void QMirClientCursor::applyDefaultCursorConfiguration(MirSurface *surface) -{ - auto cursorConfiguration = mir_cursor_configuration_from_name("left_ptr"); - mir_surface_configure_cursor(surface, cursorConfiguration); - mir_cursor_configuration_destroy(cursorConfiguration); -} diff --git a/src/plugins/platforms/mirclient/qmirclientcursor.h b/src/plugins/platforms/mirclient/qmirclientcursor.h deleted file mode 100644 index c5de23b272..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientcursor.h +++ /dev/null @@ -1,64 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015-2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef QMIRCLIENTCURSOR_H -#define QMIRCLIENTCURSOR_H - -#include <qpa/qplatformcursor.h> - -#include <QMap> -#include <QByteArray> - -struct MirConnection; -struct MirSurface; - -class QMirClientCursor : public QPlatformCursor -{ -public: - QMirClientCursor(MirConnection *connection); - void changeCursor(QCursor *windowCursor, QWindow *window) override; -private: - void configureMirCursorWithPixmapQCursor(MirSurface *surface, QCursor &cursor); - void applyDefaultCursorConfiguration(MirSurface *surface); - QMap<int, QByteArray> mShapeToCursorName; - MirConnection *mConnection; -}; - -#endif // QMIRCLIENTCURSOR_H diff --git a/src/plugins/platforms/mirclient/qmirclientdebugextension.cpp b/src/plugins/platforms/mirclient/qmirclientdebugextension.cpp deleted file mode 100644 index 9aa934083d..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientdebugextension.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#include "qmirclientdebugextension.h" - -#include "qmirclientlogging.h" - -// mir client debug -#include <mir_toolkit/debug/surface.h> - -Q_LOGGING_CATEGORY(mirclientDebug, "qt.qpa.mirclient.debug") - -QMirClientDebugExtension::QMirClientDebugExtension() - : m_mirclientDebug(QStringLiteral("mirclient-debug-extension"), 1) - , m_mapper(nullptr) -{ - qCDebug(mirclientDebug) << "NOTICE: Loading mirclient-debug-extension"; - m_mapper = (MapperPrototype) m_mirclientDebug.resolve("mir_debug_surface_coords_to_screen"); - - if (!m_mirclientDebug.isLoaded()) { - qCWarning(mirclientDebug) << "ERROR: mirclient-debug-extension failed to load:" - << m_mirclientDebug.errorString(); - } else if (!m_mapper) { - qCWarning(mirclientDebug) << "ERROR: unable to find required symbols in mirclient-debug-extension:" - << m_mirclientDebug.errorString(); - } -} - -QPoint QMirClientDebugExtension::mapSurfacePointToScreen(MirSurface *surface, const QPoint &point) -{ - if (!m_mapper) { - return point; - } - - QPoint mappedPoint; - bool status = m_mapper(surface, point.x(), point.y(), &mappedPoint.rx(), &mappedPoint.ry()); - if (status) { - return mappedPoint; - } else { - return point; - } -} diff --git a/src/plugins/platforms/mirclient/qmirclientdesktopwindow.cpp b/src/plugins/platforms/mirclient/qmirclientdesktopwindow.cpp deleted file mode 100644 index 123f805c25..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientdesktopwindow.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#include "qmirclientdesktopwindow.h" - -// local -#include "qmirclientlogging.h" - -QMirClientDesktopWindow::QMirClientDesktopWindow(QWindow *window) - : QPlatformWindow(window) -{ - qCDebug(mirclient, "QMirClientDesktopWindow(window=%p)", window); -} diff --git a/src/plugins/platforms/mirclient/qmirclientdesktopwindow.h b/src/plugins/platforms/mirclient/qmirclientdesktopwindow.h deleted file mode 100644 index 3ba54db826..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientdesktopwindow.h +++ /dev/null @@ -1,53 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef QMIRCLIENTDESKTOPWINDOW_H -#define QMIRCLIENTDESKTOPWINDOW_H - -#include <qpa/qplatformwindow.h> - -// TODO Implement it. For now it's just an empty, dummy class. -class QMirClientDesktopWindow : public QPlatformWindow -{ -public: - QMirClientDesktopWindow(QWindow*); -}; - -#endif // QMIRCLIENTDESKTOPWINDOW_H diff --git a/src/plugins/platforms/mirclient/qmirclientglcontext.cpp b/src/plugins/platforms/mirclient/qmirclientglcontext.cpp deleted file mode 100644 index fc7d90d5ec..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientglcontext.cpp +++ /dev/null @@ -1,132 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#include "qmirclientglcontext.h" -#include "qmirclientlogging.h" -#include "qmirclientwindow.h" - -#include <QOpenGLFramebufferObject> -#include <QtEglSupport/private/qeglconvenience_p.h> -#include <QtEglSupport/private/qeglpbuffer_p.h> -#include <QtGui/private/qopenglcontext_p.h> - -Q_LOGGING_CATEGORY(mirclientGraphics, "qt.qpa.mirclient.graphics", QtWarningMsg) - -namespace { - -void printEglConfig(EGLDisplay display, EGLConfig config) -{ - Q_ASSERT(display != EGL_NO_DISPLAY); - Q_ASSERT(config != nullptr); - - const char *string = eglQueryString(display, EGL_VENDOR); - qCDebug(mirclientGraphics, "EGL vendor: %s", string); - - string = eglQueryString(display, EGL_VERSION); - qCDebug(mirclientGraphics, "EGL version: %s", string); - - string = eglQueryString(display, EGL_EXTENSIONS); - qCDebug(mirclientGraphics, "EGL extensions: %s", string); - - qCDebug(mirclientGraphics, "EGL configuration attributes:"); - q_printEglConfig(display, config); -} - -} // anonymous namespace - -QMirClientOpenGLContext::QMirClientOpenGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, - EGLDisplay display) - : QEGLPlatformContext(format, share, display, 0) -{ - if (mirclientGraphics().isDebugEnabled()) { - printEglConfig(display, eglConfig()); - } -} - -static bool needsFBOReadBackWorkaround() -{ - static bool set = false; - static bool needsWorkaround = false; - - if (Q_UNLIKELY(!set)) { - const char *rendererString = reinterpret_cast<const char *>(glGetString(GL_RENDERER)); - needsWorkaround = qstrncmp(rendererString, "Mali-400", 8) == 0 - || qstrncmp(rendererString, "Mali-T7", 7) == 0 - || qstrncmp(rendererString, "PowerVR Rogue G6200", 19) == 0; - set = true; - } - - return needsWorkaround; -} - -bool QMirClientOpenGLContext::makeCurrent(QPlatformSurface* surface) -{ - const bool ret = QEGLPlatformContext::makeCurrent(surface); - - if (Q_LIKELY(ret)) { - QOpenGLContextPrivate *ctx_d = QOpenGLContextPrivate::get(context()); - if (!ctx_d->workaround_brokenFBOReadBack && needsFBOReadBackWorkaround()) { - ctx_d->workaround_brokenFBOReadBack = true; - } - } - return ret; -} - -// Following method used internally in the base class QEGLPlatformContext to access -// the egl surface of a QPlatformSurface/QMirClientWindow -EGLSurface QMirClientOpenGLContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface) -{ - if (surface->surface()->surfaceClass() == QSurface::Window) { - return static_cast<QMirClientWindow *>(surface)->eglSurface(); - } else { - return static_cast<QEGLPbuffer *>(surface)->pbuffer(); - } -} - -void QMirClientOpenGLContext::swapBuffers(QPlatformSurface* surface) -{ - QEGLPlatformContext::swapBuffers(surface); - - if (surface->surface()->surfaceClass() == QSurface::Window) { - // notify window on swap completion - auto platformWindow = static_cast<QMirClientWindow *>(surface); - platformWindow->onSwapBuffersDone(); - } -} diff --git a/src/plugins/platforms/mirclient/qmirclientglcontext.h b/src/plugins/platforms/mirclient/qmirclientglcontext.h deleted file mode 100644 index 92331a6fb1..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientglcontext.h +++ /dev/null @@ -1,63 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef QMIRCLIENTGLCONTEXT_H -#define QMIRCLIENTGLCONTEXT_H - -#include <qpa/qplatformopenglcontext.h> -#include <QtEglSupport/private/qeglplatformcontext_p.h> - -#include <EGL/egl.h> - -class QMirClientOpenGLContext : public QEGLPlatformContext -{ -public: - QMirClientOpenGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, - EGLDisplay display); - - // QEGLPlatformContext methods. - void swapBuffers(QPlatformSurface *surface) final; - bool makeCurrent(QPlatformSurface *surface) final; - -protected: - EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface) final; -}; - -#endif // QMIRCLIENTGLCONTEXT_H diff --git a/src/plugins/platforms/mirclient/qmirclientinput.cpp b/src/plugins/platforms/mirclient/qmirclientinput.cpp deleted file mode 100644 index e5319b0435..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientinput.cpp +++ /dev/null @@ -1,708 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014-2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -// Local -#include "qmirclientinput.h" -#include "qmirclientintegration.h" -#include "qmirclientnativeinterface.h" -#include "qmirclientscreen.h" -#include "qmirclientwindow.h" -#include "qmirclientlogging.h" -#include "qmirclientorientationchangeevent_p.h" - -// Qt -#include <QtCore/QThread> -#include <QtCore/qglobal.h> -#include <QtCore/QCoreApplication> -#include <QtGui/private/qguiapplication_p.h> -#include <qpa/qplatforminputcontext.h> -#include <qpa/qwindowsysteminterface.h> -#include <QTextCodec> - -#include <xkbcommon/xkbcommon.h> -#include <xkbcommon/xkbcommon-keysyms.h> - -#include <mir_toolkit/mir_client_library.h> - -Q_LOGGING_CATEGORY(mirclientInput, "qt.qpa.mirclient.input", QtWarningMsg) - -namespace -{ - -// XKB Keysyms which do not map directly to Qt types (i.e. Unicode points) -static const uint32_t KeyTable[] = { - XKB_KEY_Escape, Qt::Key_Escape, - XKB_KEY_Tab, Qt::Key_Tab, - XKB_KEY_ISO_Left_Tab, Qt::Key_Backtab, - XKB_KEY_BackSpace, Qt::Key_Backspace, - XKB_KEY_Return, Qt::Key_Return, - XKB_KEY_Insert, Qt::Key_Insert, - XKB_KEY_Delete, Qt::Key_Delete, - XKB_KEY_Clear, Qt::Key_Delete, - XKB_KEY_Pause, Qt::Key_Pause, - XKB_KEY_Print, Qt::Key_Print, - - XKB_KEY_Home, Qt::Key_Home, - XKB_KEY_End, Qt::Key_End, - XKB_KEY_Left, Qt::Key_Left, - XKB_KEY_Up, Qt::Key_Up, - XKB_KEY_Right, Qt::Key_Right, - XKB_KEY_Down, Qt::Key_Down, - XKB_KEY_Prior, Qt::Key_PageUp, - XKB_KEY_Next, Qt::Key_PageDown, - - XKB_KEY_Shift_L, Qt::Key_Shift, - XKB_KEY_Shift_R, Qt::Key_Shift, - XKB_KEY_Shift_Lock, Qt::Key_Shift, - XKB_KEY_Control_L, Qt::Key_Control, - XKB_KEY_Control_R, Qt::Key_Control, - XKB_KEY_Meta_L, Qt::Key_Meta, - XKB_KEY_Meta_R, Qt::Key_Meta, - XKB_KEY_Alt_L, Qt::Key_Alt, - XKB_KEY_Alt_R, Qt::Key_Alt, - XKB_KEY_Caps_Lock, Qt::Key_CapsLock, - XKB_KEY_Num_Lock, Qt::Key_NumLock, - XKB_KEY_Scroll_Lock, Qt::Key_ScrollLock, - XKB_KEY_Super_L, Qt::Key_Super_L, - XKB_KEY_Super_R, Qt::Key_Super_R, - XKB_KEY_Menu, Qt::Key_Menu, - XKB_KEY_Hyper_L, Qt::Key_Hyper_L, - XKB_KEY_Hyper_R, Qt::Key_Hyper_R, - XKB_KEY_Help, Qt::Key_Help, - - XKB_KEY_KP_Space, Qt::Key_Space, - XKB_KEY_KP_Tab, Qt::Key_Tab, - XKB_KEY_KP_Enter, Qt::Key_Enter, - XKB_KEY_KP_Home, Qt::Key_Home, - XKB_KEY_KP_Left, Qt::Key_Left, - XKB_KEY_KP_Up, Qt::Key_Up, - XKB_KEY_KP_Right, Qt::Key_Right, - XKB_KEY_KP_Down, Qt::Key_Down, - XKB_KEY_KP_Prior, Qt::Key_PageUp, - XKB_KEY_KP_Next, Qt::Key_PageDown, - XKB_KEY_KP_End, Qt::Key_End, - XKB_KEY_KP_Begin, Qt::Key_Clear, - XKB_KEY_KP_Insert, Qt::Key_Insert, - XKB_KEY_KP_Delete, Qt::Key_Delete, - XKB_KEY_KP_Equal, Qt::Key_Equal, - XKB_KEY_KP_Multiply, Qt::Key_Asterisk, - XKB_KEY_KP_Add, Qt::Key_Plus, - XKB_KEY_KP_Separator, Qt::Key_Comma, - XKB_KEY_KP_Subtract, Qt::Key_Minus, - XKB_KEY_KP_Decimal, Qt::Key_Period, - XKB_KEY_KP_Divide, Qt::Key_Slash, - - XKB_KEY_ISO_Level3_Shift, Qt::Key_AltGr, - XKB_KEY_Multi_key, Qt::Key_Multi_key, - XKB_KEY_Codeinput, Qt::Key_Codeinput, - XKB_KEY_SingleCandidate, Qt::Key_SingleCandidate, - XKB_KEY_MultipleCandidate, Qt::Key_MultipleCandidate, - XKB_KEY_PreviousCandidate, Qt::Key_PreviousCandidate, - - // dead keys - XKB_KEY_dead_grave, Qt::Key_Dead_Grave, - XKB_KEY_dead_acute, Qt::Key_Dead_Acute, - XKB_KEY_dead_circumflex, Qt::Key_Dead_Circumflex, - XKB_KEY_dead_tilde, Qt::Key_Dead_Tilde, - XKB_KEY_dead_macron, Qt::Key_Dead_Macron, - XKB_KEY_dead_breve, Qt::Key_Dead_Breve, - XKB_KEY_dead_abovedot, Qt::Key_Dead_Abovedot, - XKB_KEY_dead_diaeresis, Qt::Key_Dead_Diaeresis, - XKB_KEY_dead_abovering, Qt::Key_Dead_Abovering, - XKB_KEY_dead_doubleacute, Qt::Key_Dead_Doubleacute, - XKB_KEY_dead_caron, Qt::Key_Dead_Caron, - XKB_KEY_dead_cedilla, Qt::Key_Dead_Cedilla, - XKB_KEY_dead_ogonek, Qt::Key_Dead_Ogonek, - XKB_KEY_dead_iota, Qt::Key_Dead_Iota, - XKB_KEY_dead_voiced_sound, Qt::Key_Dead_Voiced_Sound, - XKB_KEY_dead_semivoiced_sound, Qt::Key_Dead_Semivoiced_Sound, - XKB_KEY_dead_belowdot, Qt::Key_Dead_Belowdot, - XKB_KEY_dead_hook, Qt::Key_Dead_Hook, - XKB_KEY_dead_horn, Qt::Key_Dead_Horn, - XKB_KEY_dead_stroke, Qt::Key_Dead_Stroke, - XKB_KEY_dead_abovecomma, Qt::Key_Dead_Abovecomma, - XKB_KEY_dead_abovereversedcomma, Qt::Key_Dead_Abovereversedcomma, - XKB_KEY_dead_doublegrave, Qt::Key_Dead_Doublegrave, - XKB_KEY_dead_belowring, Qt::Key_Dead_Belowring, - XKB_KEY_dead_belowmacron, Qt::Key_Dead_Belowmacron, - XKB_KEY_dead_belowcircumflex, Qt::Key_Dead_Belowcircumflex, - XKB_KEY_dead_belowtilde, Qt::Key_Dead_Belowtilde, - XKB_KEY_dead_belowbreve, Qt::Key_Dead_Belowbreve, - XKB_KEY_dead_belowdiaeresis, Qt::Key_Dead_Belowdiaeresis, - XKB_KEY_dead_invertedbreve, Qt::Key_Dead_Invertedbreve, - XKB_KEY_dead_belowcomma, Qt::Key_Dead_Belowcomma, - XKB_KEY_dead_currency, Qt::Key_Dead_Currency, - XKB_KEY_dead_a, Qt::Key_Dead_a, - XKB_KEY_dead_A, Qt::Key_Dead_A, - XKB_KEY_dead_e, Qt::Key_Dead_e, - XKB_KEY_dead_E, Qt::Key_Dead_E, - XKB_KEY_dead_i, Qt::Key_Dead_i, - XKB_KEY_dead_I, Qt::Key_Dead_I, - XKB_KEY_dead_o, Qt::Key_Dead_o, - XKB_KEY_dead_O, Qt::Key_Dead_O, - XKB_KEY_dead_u, Qt::Key_Dead_u, - XKB_KEY_dead_U, Qt::Key_Dead_U, - XKB_KEY_dead_small_schwa, Qt::Key_Dead_Small_Schwa, - XKB_KEY_dead_capital_schwa, Qt::Key_Dead_Capital_Schwa, - XKB_KEY_dead_greek, Qt::Key_Dead_Greek, - XKB_KEY_dead_lowline, Qt::Key_Dead_Lowline, - XKB_KEY_dead_aboveverticalline, Qt::Key_Dead_Aboveverticalline, - XKB_KEY_dead_belowverticalline, Qt::Key_Dead_Belowverticalline, - XKB_KEY_dead_longsolidusoverlay, Qt::Key_Dead_Longsolidusoverlay, - - XKB_KEY_Mode_switch, Qt::Key_Mode_switch, - XKB_KEY_script_switch, Qt::Key_Mode_switch, - XKB_KEY_XF86AudioRaiseVolume, Qt::Key_VolumeUp, - XKB_KEY_XF86AudioLowerVolume, Qt::Key_VolumeDown, - XKB_KEY_XF86PowerOff, Qt::Key_PowerOff, - XKB_KEY_XF86PowerDown, Qt::Key_PowerDown, - - 0, 0 -}; - -Qt::WindowState mirSurfaceStateToWindowState(MirSurfaceState state) -{ - switch (state) { - case mir_surface_state_fullscreen: - return Qt::WindowFullScreen; - case mir_surface_state_maximized: - case mir_surface_state_vertmaximized: - case mir_surface_state_horizmaximized: - return Qt::WindowMaximized; - case mir_surface_state_minimized: - return Qt::WindowMinimized; - case mir_surface_state_hidden: - // We should be handling this state separately. - Q_ASSERT(false); - case mir_surface_state_restored: - case mir_surface_state_unknown: - default: - return Qt::WindowNoState; - } -} - -} // namespace - -class UbuntuEvent : public QEvent -{ -public: - UbuntuEvent(QMirClientWindow* window, const MirEvent *event, QEvent::Type type) - : QEvent(type), window(window) { - nativeEvent = mir_event_ref(event); - } - ~UbuntuEvent() - { - mir_event_unref(nativeEvent); - } - - QPointer<QMirClientWindow> window; - const MirEvent *nativeEvent; -}; - -QMirClientInput::QMirClientInput(QMirClientClientIntegration* integration) - : QObject(nullptr) - , mIntegration(integration) - , mEventFilterType(static_cast<QMirClientNativeInterface*>( - integration->nativeInterface())->genericEventFilterType()) - , mEventType(static_cast<QEvent::Type>(QEvent::registerEventType())) - , mLastInputWindow(nullptr) -{ - // Initialize touch device. - mTouchDevice = new QTouchDevice; - mTouchDevice->setType(QTouchDevice::TouchScreen); - mTouchDevice->setCapabilities( - QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::Pressure | - QTouchDevice::NormalizedPosition); - QWindowSystemInterface::registerTouchDevice(mTouchDevice); -} - -QMirClientInput::~QMirClientInput() -{ - // Qt will take care of deleting mTouchDevice. -} - -static const char* nativeEventTypeToStr(MirEventType t) -{ - switch (t) - { - case mir_event_type_key: - return "key"; - case mir_event_type_motion: - return "motion"; - case mir_event_type_surface: - return "surface"; - case mir_event_type_resize: - return "resize"; - case mir_event_type_prompt_session_state_change: - return "prompt_session_state_change"; - case mir_event_type_orientation: - return "orientation"; - case mir_event_type_close_surface: - return "close_surface"; - case mir_event_type_input: - return "input"; - case mir_event_type_keymap: - return "keymap"; - case mir_event_type_input_configuration: - return "input_configuration"; - case mir_event_type_surface_output: - return "surface_output"; - case mir_event_type_input_device_state: - return "input_device_state"; - default: - return "unknown"; - } -} - -void QMirClientInput::customEvent(QEvent* event) -{ - Q_ASSERT(QThread::currentThread() == thread()); - UbuntuEvent* ubuntuEvent = static_cast<UbuntuEvent*>(event); - const MirEvent *nativeEvent = ubuntuEvent->nativeEvent; - - if ((ubuntuEvent->window == nullptr) || (ubuntuEvent->window->window() == nullptr)) { - qCWarning(mirclient) << "Attempted to deliver an event to a non-existent window, ignoring."; - return; - } - - // Event filtering. - long result; - if (QWindowSystemInterface::handleNativeEvent( - ubuntuEvent->window->window(), mEventFilterType, - const_cast<void *>(static_cast<const void *>(nativeEvent)), &result) == true) { - qCDebug(mirclient, "event filtered out by native interface"); - return; - } - - qCDebug(mirclientInput, "customEvent(type=%s)", nativeEventTypeToStr(mir_event_get_type(nativeEvent))); - - // Event dispatching. - switch (mir_event_get_type(nativeEvent)) - { - case mir_event_type_input: - dispatchInputEvent(ubuntuEvent->window, mir_event_get_input_event(nativeEvent)); - break; - case mir_event_type_resize: - { - auto resizeEvent = mir_event_get_resize_event(nativeEvent); - - // Enable workaround for Screen rotation - auto const targetWindow = ubuntuEvent->window; - if (targetWindow) { - auto const screen = static_cast<QMirClientScreen*>(targetWindow->screen()); - if (screen) { - screen->handleWindowSurfaceResize( - mir_resize_event_get_width(resizeEvent), - mir_resize_event_get_height(resizeEvent)); - } - - targetWindow->handleSurfaceResized( - mir_resize_event_get_width(resizeEvent), - mir_resize_event_get_height(resizeEvent)); - } - break; - } - case mir_event_type_surface: - handleSurfaceEvent(ubuntuEvent->window, mir_event_get_surface_event(nativeEvent)); - break; - case mir_event_type_surface_output: - handleSurfaceOutputEvent(ubuntuEvent->window, mir_event_get_surface_output_event(nativeEvent)); - break; - case mir_event_type_orientation: - dispatchOrientationEvent(ubuntuEvent->window->window(), mir_event_get_orientation_event(nativeEvent)); - break; - case mir_event_type_close_surface: - QWindowSystemInterface::handleCloseEvent(ubuntuEvent->window->window()); - break; - default: - qCDebug(mirclient, "unhandled event type: %d", static_cast<int>(mir_event_get_type(nativeEvent))); - } -} - -void QMirClientInput::postEvent(QMirClientWindow *platformWindow, const MirEvent *event) -{ - QWindow *window = platformWindow->window(); - - QCoreApplication::postEvent(this, new UbuntuEvent( - platformWindow, event, mEventType)); - - if ((window->flags().testFlag(Qt::WindowTransparentForInput)) && window->parent()) { - QCoreApplication::postEvent(this, new UbuntuEvent( - static_cast<QMirClientWindow*>(platformWindow->QPlatformWindow::parent()), - event, mEventType)); - } -} - -void QMirClientInput::dispatchInputEvent(QMirClientWindow *window, const MirInputEvent *ev) -{ - switch (mir_input_event_get_type(ev)) - { - case mir_input_event_type_key: - dispatchKeyEvent(window, ev); - break; - case mir_input_event_type_touch: - dispatchTouchEvent(window, ev); - break; - case mir_input_event_type_pointer: - dispatchPointerEvent(window, ev); - break; - default: - break; - } -} - -void QMirClientInput::dispatchTouchEvent(QMirClientWindow *window, const MirInputEvent *ev) -{ - const MirTouchEvent *tev = mir_input_event_get_touch_event(ev); - - // FIXME(loicm) Max pressure is device specific. That one is for the Samsung Galaxy Nexus. That - // needs to be fixed as soon as the compat input lib adds query support. - const float kMaxPressure = 1.28; - const QRect kWindowGeometry = window->geometry(); - QList<QWindowSystemInterface::TouchPoint> touchPoints; - - - // TODO: Is it worth setting the Qt::TouchPointStationary ones? Currently they are left - // as Qt::TouchPointMoved - const unsigned int kPointerCount = mir_touch_event_point_count(tev); - touchPoints.reserve(int(kPointerCount)); - for (unsigned int i = 0; i < kPointerCount; ++i) { - QWindowSystemInterface::TouchPoint touchPoint; - - const float kX = mir_touch_event_axis_value(tev, i, mir_touch_axis_x) + kWindowGeometry.x(); - const float kY = mir_touch_event_axis_value(tev, i, mir_touch_axis_y) + kWindowGeometry.y(); // see bug lp:1346633 workaround comments elsewhere - const float kW = mir_touch_event_axis_value(tev, i, mir_touch_axis_touch_major); - const float kH = mir_touch_event_axis_value(tev, i, mir_touch_axis_touch_minor); - const float kP = mir_touch_event_axis_value(tev, i, mir_touch_axis_pressure); - touchPoint.id = mir_touch_event_id(tev, i); - touchPoint.normalPosition = QPointF(kX / kWindowGeometry.width(), kY / kWindowGeometry.height()); - touchPoint.area = QRectF(kX - (kW / 2.0), kY - (kH / 2.0), kW, kH); - touchPoint.pressure = kP / kMaxPressure; - - MirTouchAction touch_action = mir_touch_event_action(tev, i); - switch (touch_action) - { - case mir_touch_action_down: - mLastInputWindow = window; - touchPoint.state = Qt::TouchPointPressed; - break; - case mir_touch_action_up: - touchPoint.state = Qt::TouchPointReleased; - break; - case mir_touch_action_change: - touchPoint.state = Qt::TouchPointMoved; - break; - default: - Q_UNREACHABLE(); - } - - touchPoints.append(touchPoint); - } - - ulong timestamp = mir_input_event_get_event_time(ev) / 1000000; - QWindowSystemInterface::handleTouchEvent(window->window(), timestamp, - mTouchDevice, touchPoints); -} - -static uint32_t translateKeysym(uint32_t sym, const QString &text) { - int code = 0; - - QTextCodec *systemCodec = QTextCodec::codecForLocale(); - if (sym < 128 || (sym < 256 && systemCodec->mibEnum() == 4)) { - // upper-case key, if known - code = isprint((int)sym) ? toupper((int)sym) : 0; - } else if (sym >= XKB_KEY_F1 && sym <= XKB_KEY_F35) { - return Qt::Key_F1 + (int(sym) - XKB_KEY_F1); - } else if (text.length() == 1 && text.unicode()->unicode() > 0x1f - && text.unicode()->unicode() != 0x7f - && !(sym >= XKB_KEY_dead_grave && sym <= XKB_KEY_dead_currency)) { - code = text.unicode()->toUpper().unicode(); - } else { - for (int i = 0; KeyTable[i]; i += 2) - if (sym == KeyTable[i]) - code = KeyTable[i + 1]; - } - - return code; -} - -namespace -{ -Qt::KeyboardModifiers qt_modifiers_from_mir(MirInputEventModifiers modifiers) -{ - Qt::KeyboardModifiers q_modifiers = Qt::NoModifier; - if (modifiers & mir_input_event_modifier_shift) { - q_modifiers |= Qt::ShiftModifier; - } - if (modifiers & mir_input_event_modifier_ctrl) { - q_modifiers |= Qt::ControlModifier; - } - if (modifiers & mir_input_event_modifier_alt_left) { - q_modifiers |= Qt::AltModifier; - } - if (modifiers & mir_input_event_modifier_meta) { - q_modifiers |= Qt::MetaModifier; - } - if (modifiers & mir_input_event_modifier_alt_right) { - q_modifiers |= Qt::GroupSwitchModifier; - } - return q_modifiers; -} -} - -void QMirClientInput::dispatchKeyEvent(QMirClientWindow *window, const MirInputEvent *event) -{ - const MirKeyboardEvent *key_event = mir_input_event_get_keyboard_event(event); - - ulong timestamp = mir_input_event_get_event_time(event) / 1000000; - xkb_keysym_t xk_sym = mir_keyboard_event_key_code(key_event); - quint32 scan_code = mir_keyboard_event_scan_code(key_event); - quint32 native_modifiers = mir_keyboard_event_modifiers(key_event); - - // Key modifier and unicode index mapping. - auto modifiers = qt_modifiers_from_mir(native_modifiers); - - MirKeyboardAction action = mir_keyboard_event_action(key_event); - QEvent::Type keyType = action == mir_keyboard_action_up - ? QEvent::KeyRelease : QEvent::KeyPress; - - if (action == mir_keyboard_action_down) - mLastInputWindow = window; - - QString text; - QVarLengthArray<char, 32> chars(32); - { - int result = xkb_keysym_to_utf8(xk_sym, chars.data(), chars.size()); - - if (result > 0) { - text = QString::fromUtf8(chars.constData()); - } - } - int sym = translateKeysym(xk_sym, text); - - bool is_auto_rep = action == mir_keyboard_action_repeat; - - QPlatformInputContext *context = QGuiApplicationPrivate::platformIntegration()->inputContext(); - if (context) { - QKeyEvent qKeyEvent(keyType, sym, modifiers, scan_code, xk_sym, native_modifiers, text, is_auto_rep); - qKeyEvent.setTimestamp(timestamp); - if (context->filterEvent(&qKeyEvent)) { - qCDebug(mirclient, "key event filtered out by input context"); - return; - } - } - - QWindowSystemInterface::handleExtendedKeyEvent(window->window(), timestamp, keyType, sym, modifiers, scan_code, xk_sym, native_modifiers, text, is_auto_rep); -} - -namespace -{ -Qt::MouseButtons extract_buttons(const MirPointerEvent *pev) -{ - Qt::MouseButtons buttons = Qt::NoButton; - if (mir_pointer_event_button_state(pev, mir_pointer_button_primary)) - buttons |= Qt::LeftButton; - if (mir_pointer_event_button_state(pev, mir_pointer_button_secondary)) - buttons |= Qt::RightButton; - if (mir_pointer_event_button_state(pev, mir_pointer_button_tertiary)) - buttons |= Qt::MiddleButton; - if (mir_pointer_event_button_state(pev, mir_pointer_button_back)) - buttons |= Qt::BackButton; - if (mir_pointer_event_button_state(pev, mir_pointer_button_forward)) - buttons |= Qt::ForwardButton; - - return buttons; -} -} - -void QMirClientInput::dispatchPointerEvent(QMirClientWindow *platformWindow, const MirInputEvent *ev) -{ - const auto window = platformWindow->window(); - const auto timestamp = mir_input_event_get_event_time(ev) / 1000000; - - const auto pev = mir_input_event_get_pointer_event(ev); - const auto action = mir_pointer_event_action(pev); - - const auto modifiers = qt_modifiers_from_mir(mir_pointer_event_modifiers(pev)); - const auto localPoint = QPointF(mir_pointer_event_axis_value(pev, mir_pointer_axis_x), - mir_pointer_event_axis_value(pev, mir_pointer_axis_y)); - - mLastInputWindow = platformWindow; - - switch (action) { - case mir_pointer_action_button_up: - case mir_pointer_action_button_down: - case mir_pointer_action_motion: - { - const float hDelta = mir_pointer_event_axis_value(pev, mir_pointer_axis_hscroll); - const float vDelta = mir_pointer_event_axis_value(pev, mir_pointer_axis_vscroll); - - if (hDelta != 0 || vDelta != 0) { - // QWheelEvent::DefaultDeltasPerStep = 120 but doesn't exist on vivid - const QPoint angleDelta(120 * hDelta, 120 * vDelta); - QWindowSystemInterface::handleWheelEvent(window, timestamp, localPoint, window->position() + localPoint, - QPoint(), angleDelta, modifiers, Qt::ScrollUpdate); - } - auto buttons = extract_buttons(pev); - QWindowSystemInterface::handleMouseEvent(window, timestamp, localPoint, window->position() + localPoint /* Should we omit global point instead? */, - buttons, modifiers); - break; - } - case mir_pointer_action_enter: - QWindowSystemInterface::handleEnterEvent(window, localPoint, window->position() + localPoint); - break; - case mir_pointer_action_leave: - QWindowSystemInterface::handleLeaveEvent(window); - break; - default: - Q_UNREACHABLE(); - } -} - -static const char* nativeOrientationDirectionToStr(MirOrientation orientation) -{ - switch (orientation) { - case mir_orientation_normal: - return "Normal"; - case mir_orientation_left: - return "Left"; - case mir_orientation_inverted: - return "Inverted"; - case mir_orientation_right: - return "Right"; - } - Q_UNREACHABLE(); -} - -void QMirClientInput::dispatchOrientationEvent(QWindow *window, const MirOrientationEvent *event) -{ - MirOrientation mir_orientation = mir_orientation_event_get_direction(event); - qCDebug(mirclientInput, "orientation direction: %s", nativeOrientationDirectionToStr(mir_orientation)); - - if (!window->screen()) { - qCDebug(mirclient, "Window has no associated screen, dropping orientation event"); - return; - } - - OrientationChangeEvent::Orientation orientation; - switch (mir_orientation) { - case mir_orientation_normal: - orientation = OrientationChangeEvent::TopUp; - break; - case mir_orientation_left: - orientation = OrientationChangeEvent::LeftUp; - break; - case mir_orientation_inverted: - orientation = OrientationChangeEvent::TopDown; - break; - case mir_orientation_right: - orientation = OrientationChangeEvent::RightUp; - break; - default: - qCDebug(mirclient, "No such orientation %d", mir_orientation); - return; - } - - // Dispatch orientation event to [Platform]Screen, as that is where Qt reads it. Screen will handle - // notifying Qt of the actual orientation change - done to prevent multiple Windows each creating - // an identical orientation change event and passing it directly to Qt. - // [Platform]Screen can also factor in the native orientation. - QCoreApplication::postEvent(static_cast<QMirClientScreen*>(window->screen()->handle()), - new OrientationChangeEvent(OrientationChangeEvent::mType, orientation)); -} - -void QMirClientInput::handleSurfaceEvent(const QPointer<QMirClientWindow> &window, const MirSurfaceEvent *event) -{ - auto surfaceEventAttribute = mir_surface_event_get_attribute(event); - - switch (surfaceEventAttribute) { - case mir_surface_attrib_focus: { - window->handleSurfaceFocusChanged( - mir_surface_event_get_attribute_value(event) == mir_surface_focused); - break; - } - case mir_surface_attrib_visibility: { - window->handleSurfaceExposeChange( - mir_surface_event_get_attribute_value(event) == mir_surface_visibility_exposed); - break; - } - // Remaining attributes are ones client sets for server, and server should not override them - case mir_surface_attrib_state: { - MirSurfaceState state = static_cast<MirSurfaceState>(mir_surface_event_get_attribute_value(event)); - - if (state == mir_surface_state_hidden) { - window->handleSurfaceVisibilityChanged(false); - } else { - // it's visible! - window->handleSurfaceVisibilityChanged(true); - window->handleSurfaceStateChanged(mirSurfaceStateToWindowState(state)); - } - break; - } - case mir_surface_attrib_type: - case mir_surface_attrib_swapinterval: - case mir_surface_attrib_dpi: - case mir_surface_attrib_preferred_orientation: - case mir_surface_attribs: - break; - } -} - -void QMirClientInput::handleSurfaceOutputEvent(const QPointer<QMirClientWindow> &window, const MirSurfaceOutputEvent *event) -{ - const uint32_t outputId = mir_surface_output_event_get_output_id(event); - const int dpi = mir_surface_output_event_get_dpi(event); - const MirFormFactor formFactor = mir_surface_output_event_get_form_factor(event); - const float scale = mir_surface_output_event_get_scale(event); - - const auto screenObserver = mIntegration->screenObserver(); - QMirClientScreen *screen = screenObserver->findScreenWithId(outputId); - if (!screen) { - qCWarning(mirclient) << "Mir notified window" << window->window() << "on an unknown screen with id" << outputId; - return; - } - - screenObserver->handleScreenPropertiesChange(screen, dpi, formFactor, scale); - window->handleScreenPropertiesChange(formFactor, scale); - - if (window->screen() != screen) { - QWindowSystemInterface::handleWindowScreenChanged(window->window(), screen->screen()); - } -} diff --git a/src/plugins/platforms/mirclient/qmirclientinput.h b/src/plugins/platforms/mirclient/qmirclientinput.h deleted file mode 100644 index 263cb5e54e..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientinput.h +++ /dev/null @@ -1,86 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014-2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef QMIRCLIENTINPUT_H -#define QMIRCLIENTINPUT_H - -// Qt -#include <qpa/qwindowsysteminterface.h> - -#include <mir_toolkit/mir_client_library.h> - -class QMirClientClientIntegration; -class QMirClientWindow; - -class QMirClientInput : public QObject -{ - Q_OBJECT - -public: - QMirClientInput(QMirClientClientIntegration* integration); - virtual ~QMirClientInput(); - - // QObject methods. - void customEvent(QEvent* event) override; - - void postEvent(QMirClientWindow* window, const MirEvent *event); - QMirClientClientIntegration* integration() const { return mIntegration; } - QMirClientWindow *lastInputWindow() const {return mLastInputWindow; } - -protected: - void dispatchKeyEvent(QMirClientWindow *window, const MirInputEvent *event); - void dispatchPointerEvent(QMirClientWindow *window, const MirInputEvent *event); - void dispatchTouchEvent(QMirClientWindow *window, const MirInputEvent *event); - void dispatchInputEvent(QMirClientWindow *window, const MirInputEvent *event); - - void dispatchOrientationEvent(QWindow* window, const MirOrientationEvent *event); - void handleSurfaceEvent(const QPointer<QMirClientWindow> &window, const MirSurfaceEvent *event); - void handleSurfaceOutputEvent(const QPointer<QMirClientWindow> &window, const MirSurfaceOutputEvent *event); - -private: - QMirClientClientIntegration* mIntegration; - QTouchDevice* mTouchDevice; - const QByteArray mEventFilterType; - const QEvent::Type mEventType; - - QMirClientWindow *mLastInputWindow; -}; - -#endif // QMIRCLIENTINPUT_H diff --git a/src/plugins/platforms/mirclient/qmirclientintegration.cpp b/src/plugins/platforms/mirclient/qmirclientintegration.cpp deleted file mode 100644 index d2b1dbee0d..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientintegration.cpp +++ /dev/null @@ -1,412 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014-2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -// Local -#include "qmirclientintegration.h" -#include "qmirclientbackingstore.h" -#include "qmirclientclipboard.h" -#include "qmirclientdebugextension.h" -#include "qmirclientdesktopwindow.h" -#include "qmirclientglcontext.h" -#include "qmirclientinput.h" -#include "qmirclientlogging.h" -#include "qmirclientnativeinterface.h" -#include "qmirclientscreen.h" -#include "qmirclienttheme.h" -#include "qmirclientwindow.h" - -// Qt -#include <QFileInfo> -#include <QGuiApplication> -#include <qpa/qplatformnativeinterface.h> -#include <qpa/qplatforminputcontextfactory_p.h> -#include <qpa/qplatforminputcontext.h> -#include <qpa/qwindowsysteminterface.h> -#include <QtEglSupport/private/qeglconvenience_p.h> -#include <QtEglSupport/private/qeglpbuffer_p.h> -#include <QtFontDatabaseSupport/private/qgenericunixfontdatabase_p.h> -#include <QtEventDispatcherSupport/private/qgenericunixeventdispatcher_p.h> -#ifndef QT_NO_ACCESSIBILITY -#include <qpa/qplatformaccessibility.h> -#ifndef QT_NO_ACCESSIBILITY_ATSPI_BRIDGE -#include <QtLinuxAccessibilitySupport/private/bridge_p.h> -#endif -#endif - -#include <QOpenGLContext> -#include <QOffscreenSurface> - -// platform-api -#include <ubuntu/application/lifecycle_delegate.h> -#include <ubuntu/application/id.h> -#include <ubuntu/application/options.h> - -static void resumedCallback(const UApplicationOptions */*options*/, void* context) -{ - auto integration = static_cast<QMirClientClientIntegration*>(context); - integration->appStateController()->setResumed(); -} - -static void aboutToStopCallback(UApplicationArchive */*archive*/, void* context) -{ - auto integration = static_cast<QMirClientClientIntegration*>(context); - auto inputContext = integration->inputContext(); - if (inputContext) { - inputContext->hideInputPanel(); - } else { - qCWarning(mirclient) << "aboutToStopCallback(): no input context"; - } - integration->appStateController()->setSuspended(); -} - -QMirClientClientIntegration::QMirClientClientIntegration(int argc, char **argv) - : QPlatformIntegration() - , mNativeInterface(new QMirClientNativeInterface(this)) - , mFontDb(new QGenericUnixFontDatabase) - , mServices(new QMirClientPlatformServices) - , mAppStateController(new QMirClientAppStateController) - , mScaleFactor(1.0) -{ - { - QStringList args = QCoreApplication::arguments(); - setupOptions(args); - QByteArray sessionName = generateSessionName(args); - setupDescription(sessionName); - } - - // Create new application instance - mInstance = u_application_instance_new_from_description_with_options(mDesc, mOptions); - - if (Q_UNLIKELY(!mInstance)) - qFatal("QMirClientClientIntegration: connection to Mir server failed. Check that a Mir server is\n" - "running, and the correct socket is being used and is accessible. The shell may have\n" - "rejected the incoming connection, so check its log file"); - - mMirConnection = u_application_instance_get_mir_connection(mInstance); - - // Choose the default surface format suited to the Mir platform - QSurfaceFormat defaultFormat; - defaultFormat.setRedBufferSize(8); - defaultFormat.setGreenBufferSize(8); - defaultFormat.setBlueBufferSize(8); - QSurfaceFormat::setDefaultFormat(defaultFormat); - - // Initialize EGL. - mEglNativeDisplay = mir_connection_get_egl_native_display(mMirConnection); - ASSERT((mEglDisplay = eglGetDisplay(mEglNativeDisplay)) != EGL_NO_DISPLAY); - ASSERT(eglInitialize(mEglDisplay, nullptr, nullptr) == EGL_TRUE); - - // Has debug mode been requsted, either with "-testability" switch or QT_LOAD_TESTABILITY env var - bool testability = qEnvironmentVariableIsSet("QT_LOAD_TESTABILITY"); - for (int i=1; !testability && i<argc; i++) { - if (strcmp(argv[i], "-testability") == 0) { - testability = true; - } - } - if (testability) { - mDebugExtension.reset(new QMirClientDebugExtension); - } -} - -void QMirClientClientIntegration::initialize() -{ - // Init the ScreenObserver - mScreenObserver.reset(new QMirClientScreenObserver(mMirConnection)); - connect(mScreenObserver.data(), &QMirClientScreenObserver::screenAdded, - [this](QMirClientScreen *screen) { QWindowSystemInterface::handleScreenAdded(screen); }); - connect(mScreenObserver.data(), &QMirClientScreenObserver::screenRemoved, - this, &QMirClientClientIntegration::destroyScreen); - - Q_FOREACH (auto screen, mScreenObserver->screens()) { - QWindowSystemInterface::handleScreenAdded(screen); - } - - // Initialize input. - mInput = new QMirClientInput(this); - mInputContext = QPlatformInputContextFactory::create(); - - // compute the scale factor - const int defaultGridUnit = 8; - int gridUnit = defaultGridUnit; - QByteArray gridUnitString = qgetenv("GRID_UNIT_PX"); - if (!gridUnitString.isEmpty()) { - bool ok; - gridUnit = gridUnitString.toInt(&ok); - if (!ok) { - gridUnit = defaultGridUnit; - } - } - mScaleFactor = static_cast<qreal>(gridUnit) / defaultGridUnit; -} - -QMirClientClientIntegration::~QMirClientClientIntegration() -{ - eglTerminate(mEglDisplay); - delete mInput; - delete mInputContext; - delete mServices; -} - -QPlatformServices *QMirClientClientIntegration::services() const -{ - return mServices; -} - -void QMirClientClientIntegration::setupOptions(QStringList &args) -{ - int argc = args.size() + 1; - char **argv = new char*[argc]; - for (int i = 0; i < argc - 1; i++) - argv[i] = qstrdup(args.at(i).toLocal8Bit()); - argv[argc - 1] = nullptr; - - mOptions = u_application_options_new_from_cmd_line(argc - 1, argv); - - for (int i = 0; i < argc; i++) - delete [] argv[i]; - delete [] argv; -} - -void QMirClientClientIntegration::setupDescription(QByteArray &sessionName) -{ - mDesc = u_application_description_new(); - - UApplicationId* id = u_application_id_new_from_stringn(sessionName.data(), sessionName.count()); - u_application_description_set_application_id(mDesc, id); - - UApplicationLifecycleDelegate* delegate = u_application_lifecycle_delegate_new(); - u_application_lifecycle_delegate_set_application_resumed_cb(delegate, &resumedCallback); - u_application_lifecycle_delegate_set_application_about_to_stop_cb(delegate, &aboutToStopCallback); - u_application_lifecycle_delegate_set_context(delegate, this); - u_application_description_set_application_lifecycle_delegate(mDesc, delegate); -} - -QByteArray QMirClientClientIntegration::generateSessionName(QStringList &args) -{ - // Try to come up with some meaningful session name to uniquely identify this session, - // helping with shell debugging - - if (args.count() == 0) { - return QByteArray("QtUbuntu"); - } if (args[0].contains("qmlscene")) { - return generateSessionNameFromQmlFile(args); - } else { - // use the executable name - QFileInfo fileInfo(args[0]); - return fileInfo.fileName().toLocal8Bit(); - } -} - -QByteArray QMirClientClientIntegration::generateSessionNameFromQmlFile(QStringList &args) -{ - Q_FOREACH (QString arg, args) { - if (arg.endsWith(".qml")) { - QFileInfo fileInfo(arg); - return fileInfo.fileName().toLocal8Bit(); - } - } - - // give up - return "qmlscene"; -} - -QPlatformWindow* QMirClientClientIntegration::createPlatformWindow(QWindow* window) const -{ - if (window->type() == Qt::Desktop) { - // Desktop windows should not be backed up by a mir surface as they don't draw anything (nor should). - return new QMirClientDesktopWindow(window); - } else { - return new QMirClientWindow(window, mInput, mNativeInterface, mAppStateController.data(), - mEglDisplay, mMirConnection, mDebugExtension.data()); - } -} - -bool QMirClientClientIntegration::hasCapability(QPlatformIntegration::Capability cap) const -{ - switch (cap) { - case ThreadedOpenGL: - if (qEnvironmentVariableIsEmpty("QTUBUNTU_NO_THREADED_OPENGL")) { - return true; - } else { - qCDebug(mirclient, "disabled threaded OpenGL"); - return false; - } - - case ThreadedPixmaps: - case OpenGL: - case ApplicationState: - case MultipleWindows: - case NonFullScreenWindows: -#if QT_VERSION > QT_VERSION_CHECK(5, 5, 0) - case SwitchableWidgetComposition: -#endif - case RasterGLSurface: // needed for QQuickWidget - return true; - default: - return QPlatformIntegration::hasCapability(cap); - } -} - -QAbstractEventDispatcher *QMirClientClientIntegration::createEventDispatcher() const -{ - return createUnixEventDispatcher(); -} - -QPlatformBackingStore* QMirClientClientIntegration::createPlatformBackingStore(QWindow* window) const -{ - return new QMirClientBackingStore(window); -} - -QPlatformOpenGLContext* QMirClientClientIntegration::createPlatformOpenGLContext( - QOpenGLContext* context) const -{ - QSurfaceFormat format(context->format()); - - auto platformContext = new QMirClientOpenGLContext(format, context->shareHandle(), mEglDisplay); - if (!platformContext->isValid()) { - // Older Intel Atom-based devices only support OpenGL 1.4 compatibility profile but by default - // QML asks for at least OpenGL 2.0. The XCB GLX backend ignores this request and returns a - // 1.4 context, but the XCB EGL backend tries to honor it, and fails. The 1.4 context appears to - // have sufficient capabilities on MESA (i915) to render correctly however. So reduce the default - // requested OpenGL version to 1.0 to ensure EGL will give us a working context (lp:1549455). - static const bool isMesa = QString(eglQueryString(mEglDisplay, EGL_VENDOR)).contains(QStringLiteral("Mesa")); - if (isMesa) { - qCDebug(mirclientGraphics, "Attempting to choose OpenGL 1.4 context which may suit Mesa"); - format.setMajorVersion(1); - format.setMinorVersion(4); - delete platformContext; - platformContext = new QMirClientOpenGLContext(format, context->shareHandle(), mEglDisplay); - } - } - return platformContext; -} - -QStringList QMirClientClientIntegration::themeNames() const -{ - return QStringList(QMirClientTheme::name); -} - -QPlatformTheme* QMirClientClientIntegration::createPlatformTheme(const QString& name) const -{ - Q_UNUSED(name); - return new QMirClientTheme; -} - -QVariant QMirClientClientIntegration::styleHint(StyleHint hint) const -{ - switch (hint) { - case QPlatformIntegration::StartDragDistance: { - // default is 10 pixels (see QPlatformTheme::defaultThemeHint) - return 10.0 * mScaleFactor; - } - case QPlatformIntegration::PasswordMaskDelay: { - // return time in milliseconds - 1 second - return QVariant(1000); - } - default: - break; - } - return QPlatformIntegration::styleHint(hint); -} - -QPlatformClipboard* QMirClientClientIntegration::clipboard() const -{ - static QPlatformClipboard *clipboard = nullptr; - if (!clipboard) { - clipboard = new QMirClientClipboard; - } - return clipboard; -} - -QPlatformNativeInterface* QMirClientClientIntegration::nativeInterface() const -{ - return mNativeInterface; -} - -QPlatformOffscreenSurface *QMirClientClientIntegration::createPlatformOffscreenSurface( - QOffscreenSurface *surface) const -{ - return new QEGLPbuffer(mEglDisplay, surface->requestedFormat(), surface); -} - -void QMirClientClientIntegration::destroyScreen(QMirClientScreen *screen) -{ - // FIXME: on deleting a screen while a Window is on it, Qt will automatically - // move the window to the primaryScreen(). This will trigger a screenChanged - // signal, causing things like QQuickScreenAttached to re-fetch screen properties - // like DPI and physical size. However this is crashing, as Qt is calling virtual - // functions on QPlatformScreen, for reasons unclear. As workaround, move window - // to primaryScreen() before deleting the screen. Might be QTBUG-38650 - - QScreen *primaryScreen = QGuiApplication::primaryScreen(); - if (screen != primaryScreen->handle()) { - uint32_t movedWindowCount = 0; - Q_FOREACH (QWindow *w, QGuiApplication::topLevelWindows()) { - if (w->screen()->handle() == screen) { - QWindowSystemInterface::handleWindowScreenChanged(w, primaryScreen); - ++movedWindowCount; - } - } - if (movedWindowCount > 0) { - QWindowSystemInterface::flushWindowSystemEvents(); - } - } - - qCDebug(mirclient) << "Removing Screen with id" << screen->mirOutputId() << "and geometry" << screen->geometry(); -#if QT_VERSION < QT_VERSION_CHECK(5, 5, 0) - delete screen; -#else - QWindowSystemInterface::handleScreenRemoved(screen); -#endif -} - -#ifndef QT_NO_ACCESSIBILITY -QPlatformAccessibility *QMirClientClientIntegration::accessibility() const -{ -#if !defined(QT_NO_ACCESSIBILITY_ATSPI_BRIDGE) - if (!mAccessibility) { - Q_ASSERT_X(QCoreApplication::eventDispatcher(), "QMirClientIntegration", - "Initializing accessibility without event-dispatcher!"); - mAccessibility.reset(new QSpiAccessibleBridge()); - } -#endif - return mAccessibility.data(); -} -#endif diff --git a/src/plugins/platforms/mirclient/qmirclientintegration.h b/src/plugins/platforms/mirclient/qmirclientintegration.h deleted file mode 100644 index 035117f4da..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientintegration.h +++ /dev/null @@ -1,131 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef QMIRCLIENTINTEGRATION_H -#define QMIRCLIENTINTEGRATION_H - -#include <qpa/qplatformintegration.h> -#include <QSharedPointer> - -#include "qmirclientappstatecontroller.h" -#include "qmirclientplatformservices.h" -#include "qmirclientscreenobserver.h" - -// platform-api -#include <ubuntu/application/description.h> -#include <ubuntu/application/instance.h> - -#include <EGL/egl.h> - -class QMirClientDebugExtension; -class QMirClientInput; -class QMirClientNativeInterface; -class QMirClientScreen; -class MirConnection; - -class QMirClientClientIntegration : public QObject, public QPlatformIntegration -{ - Q_OBJECT - -public: - QMirClientClientIntegration(int argc, char **argv); - virtual ~QMirClientClientIntegration(); - - // QPlatformIntegration methods. - bool hasCapability(QPlatformIntegration::Capability cap) const override; - QAbstractEventDispatcher *createEventDispatcher() const override; - QPlatformNativeInterface* nativeInterface() const override; - QPlatformBackingStore* createPlatformBackingStore(QWindow* window) const override; - QPlatformOpenGLContext* createPlatformOpenGLContext(QOpenGLContext* context) const override; - QPlatformFontDatabase* fontDatabase() const override { return mFontDb; } - QStringList themeNames() const override; - QPlatformTheme* createPlatformTheme(const QString& name) const override; - QVariant styleHint(StyleHint hint) const override; - QPlatformServices *services() const override; - QPlatformWindow* createPlatformWindow(QWindow* window) const override; - QPlatformInputContext* inputContext() const override { return mInputContext; } - QPlatformClipboard* clipboard() const override; - void initialize() override; - QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const override; - QPlatformAccessibility *accessibility() const override; - - // New methods. - MirConnection *mirConnection() const { return mMirConnection; } - EGLDisplay eglDisplay() const { return mEglDisplay; } - EGLNativeDisplayType eglNativeDisplay() const { return mEglNativeDisplay; } - QMirClientAppStateController *appStateController() const { return mAppStateController.data(); } - QMirClientScreenObserver *screenObserver() const { return mScreenObserver.data(); } - QMirClientDebugExtension *debugExtension() const { return mDebugExtension.data(); } - -private Q_SLOTS: - void destroyScreen(QMirClientScreen *screen); - -private: - void setupOptions(QStringList &args); - void setupDescription(QByteArray &sessionName); - static QByteArray generateSessionName(QStringList &args); - static QByteArray generateSessionNameFromQmlFile(QStringList &args); - - QMirClientNativeInterface* mNativeInterface; - QPlatformFontDatabase* mFontDb; - - QMirClientPlatformServices* mServices; - - QMirClientInput* mInput; - QPlatformInputContext* mInputContext; - mutable QScopedPointer<QPlatformAccessibility> mAccessibility; - QScopedPointer<QMirClientDebugExtension> mDebugExtension; - QScopedPointer<QMirClientScreenObserver> mScreenObserver; - QScopedPointer<QMirClientAppStateController> mAppStateController; - qreal mScaleFactor; - - MirConnection *mMirConnection; - - // Platform API stuff - UApplicationOptions* mOptions; - UApplicationDescription* mDesc; - UApplicationInstance* mInstance; - - // EGL related - EGLDisplay mEglDisplay{EGL_NO_DISPLAY}; - EGLNativeDisplayType mEglNativeDisplay; -}; - -#endif // QMIRCLIENTINTEGRATION_H diff --git a/src/plugins/platforms/mirclient/qmirclientlogging.h b/src/plugins/platforms/mirclient/qmirclientlogging.h deleted file mode 100644 index 4921864ced..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientlogging.h +++ /dev/null @@ -1,55 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef QMIRCLIENTLOGGING_H -#define QMIRCLIENTLOGGING_H - -#include <QLoggingCategory> - -#define ASSERT(cond) ((!(cond)) ? qt_assert(#cond,__FILE__,__LINE__) : qt_noop()) - -Q_DECLARE_LOGGING_CATEGORY(mirclient) -Q_DECLARE_LOGGING_CATEGORY(mirclientBufferSwap) -Q_DECLARE_LOGGING_CATEGORY(mirclientInput) -Q_DECLARE_LOGGING_CATEGORY(mirclientGraphics) -Q_DECLARE_LOGGING_CATEGORY(mirclientCursor) -Q_DECLARE_LOGGING_CATEGORY(mirclientDebug) - -#endif // QMIRCLIENTLOGGING_H diff --git a/src/plugins/platforms/mirclient/qmirclientnativeinterface.cpp b/src/plugins/platforms/mirclient/qmirclientnativeinterface.cpp deleted file mode 100644 index b85e6fedfa..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientnativeinterface.cpp +++ /dev/null @@ -1,217 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -// Local -#include "qmirclientnativeinterface.h" -#include "qmirclientscreen.h" -#include "qmirclientglcontext.h" -#include "qmirclientwindow.h" - -// Qt -#include <QtGui/private/qguiapplication_p.h> -#include <QtGui/qopenglcontext.h> -#include <QtGui/qscreen.h> -#include <QtCore/QMap> - -class UbuntuResourceMap : public QMap<QByteArray, QMirClientNativeInterface::ResourceType> -{ -public: - UbuntuResourceMap() - : QMap<QByteArray, QMirClientNativeInterface::ResourceType>() { - insert("egldisplay", QMirClientNativeInterface::EglDisplay); - insert("eglcontext", QMirClientNativeInterface::EglContext); - insert("nativeorientation", QMirClientNativeInterface::NativeOrientation); - insert("display", QMirClientNativeInterface::Display); - insert("mirconnection", QMirClientNativeInterface::MirConnection); - insert("mirsurface", QMirClientNativeInterface::MirSurface); - insert("scale", QMirClientNativeInterface::Scale); - insert("formfactor", QMirClientNativeInterface::FormFactor); - } -}; - -Q_GLOBAL_STATIC(UbuntuResourceMap, ubuntuResourceMap) - -QMirClientNativeInterface::QMirClientNativeInterface(const QMirClientClientIntegration *integration) - : mIntegration(integration) - , mGenericEventFilterType(QByteArrayLiteral("Event")) - , mNativeOrientation(nullptr) -{ -} - -QMirClientNativeInterface::~QMirClientNativeInterface() -{ - delete mNativeOrientation; - mNativeOrientation = nullptr; -} - -void* QMirClientNativeInterface::nativeResourceForIntegration(const QByteArray &resourceString) -{ - const QByteArray lowerCaseResource = resourceString.toLower(); - - if (!ubuntuResourceMap()->contains(lowerCaseResource)) { - return nullptr; - } - - const ResourceType resourceType = ubuntuResourceMap()->value(lowerCaseResource); - - if (resourceType == QMirClientNativeInterface::MirConnection) { - return mIntegration->mirConnection(); - } else { - return nullptr; - } -} - -void* QMirClientNativeInterface::nativeResourceForContext( - const QByteArray& resourceString, QOpenGLContext* context) -{ - if (!context) - return nullptr; - - const QByteArray kLowerCaseResource = resourceString.toLower(); - - if (!ubuntuResourceMap()->contains(kLowerCaseResource)) - return nullptr; - - const ResourceType kResourceType = ubuntuResourceMap()->value(kLowerCaseResource); - - if (kResourceType == QMirClientNativeInterface::EglContext) - return static_cast<QMirClientOpenGLContext*>(context->handle())->eglContext(); - else - return nullptr; -} - -void* QMirClientNativeInterface::nativeResourceForWindow(const QByteArray& resourceString, QWindow* window) -{ - const QByteArray kLowerCaseResource = resourceString.toLower(); - if (!ubuntuResourceMap()->contains(kLowerCaseResource)) - return NULL; - const ResourceType kResourceType = ubuntuResourceMap()->value(kLowerCaseResource); - - switch (kResourceType) { - case EglDisplay: - return mIntegration->eglDisplay(); - case NativeOrientation: - // Return the device's native screen orientation. - if (window) { - QMirClientScreen *ubuntuScreen = static_cast<QMirClientScreen*>(window->screen()->handle()); - mNativeOrientation = new Qt::ScreenOrientation(ubuntuScreen->nativeOrientation()); - } else { - QPlatformScreen *platformScreen = QGuiApplication::primaryScreen()->handle(); - mNativeOrientation = new Qt::ScreenOrientation(platformScreen->nativeOrientation()); - } - return mNativeOrientation; - case MirSurface: - if (window) { - auto ubuntuWindow = static_cast<QMirClientWindow*>(window->handle()); - if (ubuntuWindow) { - return ubuntuWindow->mirSurface(); - } else { - return nullptr; - } - } else { - return nullptr; - } - default: - return nullptr; - } -} - -void* QMirClientNativeInterface::nativeResourceForScreen(const QByteArray& resourceString, QScreen* screen) -{ - const QByteArray kLowerCaseResource = resourceString.toLower(); - if (!ubuntuResourceMap()->contains(kLowerCaseResource)) - return NULL; - const ResourceType kResourceType = ubuntuResourceMap()->value(kLowerCaseResource); - if (!screen) - screen = QGuiApplication::primaryScreen(); - auto ubuntuScreen = static_cast<QMirClientScreen*>(screen->handle()); - if (kResourceType == QMirClientNativeInterface::Display) { - return mIntegration->eglNativeDisplay(); - // Changes to the following properties are emitted via the QMirClientNativeInterface::screenPropertyChanged - // signal fired by QMirClientScreen. Connect to this signal for these properties updates. - // WARNING: code highly thread unsafe! - } else if (kResourceType == QMirClientNativeInterface::Scale) { - // In application code, read with: - // float scale = *reinterpret_cast<float*>(nativeResourceForScreen("scale", screen())); - return &ubuntuScreen->mScale; - } else if (kResourceType == QMirClientNativeInterface::FormFactor) { - return &ubuntuScreen->mFormFactor; - } else - return NULL; -} - -// Changes to these properties are emitted via the QMirClientNativeInterface::windowPropertyChanged -// signal fired by QMirClientWindow. Connect to this signal for these properties updates. -QVariantMap QMirClientNativeInterface::windowProperties(QPlatformWindow *window) const -{ - QVariantMap propertyMap; - auto w = static_cast<QMirClientWindow*>(window); - if (w) { - propertyMap.insert("scale", w->scale()); - propertyMap.insert("formFactor", w->formFactor()); - } - return propertyMap; -} - -QVariant QMirClientNativeInterface::windowProperty(QPlatformWindow *window, const QString &name) const -{ - auto w = static_cast<QMirClientWindow*>(window); - if (!w) { - return QVariant(); - } - - if (name == QStringLiteral("scale")) { - return w->scale(); - } else if (name == QStringLiteral("formFactor")) { - return w->formFactor(); - } else { - return QVariant(); - } -} - -QVariant QMirClientNativeInterface::windowProperty(QPlatformWindow *window, const QString &name, const QVariant &defaultValue) const -{ - QVariant returnVal = windowProperty(window, name); - if (!returnVal.isValid()) { - return defaultValue; - } else { - return returnVal; - } -} diff --git a/src/plugins/platforms/mirclient/qmirclientnativeinterface.h b/src/plugins/platforms/mirclient/qmirclientnativeinterface.h deleted file mode 100644 index eb601de301..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientnativeinterface.h +++ /dev/null @@ -1,83 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef QMIRCLIENTNATIVEINTERFACE_H -#define QMIRCLIENTNATIVEINTERFACE_H - -#include <qpa/qplatformnativeinterface.h> - -#include "qmirclientintegration.h" - -class QPlatformScreen; - -class QMirClientNativeInterface : public QPlatformNativeInterface { - Q_OBJECT -public: - enum ResourceType { EglDisplay, EglContext, NativeOrientation, Display, MirConnection, MirSurface, Scale, FormFactor }; - - QMirClientNativeInterface(const QMirClientClientIntegration *integration); - ~QMirClientNativeInterface(); - - // QPlatformNativeInterface methods. - void* nativeResourceForIntegration(const QByteArray &resource) override; - void* nativeResourceForContext(const QByteArray& resourceString, - QOpenGLContext* context) override; - void* nativeResourceForWindow(const QByteArray& resourceString, - QWindow* window) override; - void* nativeResourceForScreen(const QByteArray& resourceString, - QScreen* screen) override; - - QVariantMap windowProperties(QPlatformWindow *window) const override; - QVariant windowProperty(QPlatformWindow *window, const QString &name) const override; - QVariant windowProperty(QPlatformWindow *window, const QString &name, const QVariant &defaultValue) const override; - - // New methods. - const QByteArray& genericEventFilterType() const { return mGenericEventFilterType; } - -Q_SIGNALS: // New signals - void screenPropertyChanged(QPlatformScreen *screen, const QString &propertyName); - -private: - const QMirClientClientIntegration *mIntegration; - const QByteArray mGenericEventFilterType; - Qt::ScreenOrientation* mNativeOrientation; -}; - -#endif // QMIRCLIENTNATIVEINTERFACE_H diff --git a/src/plugins/platforms/mirclient/qmirclientorientationchangeevent_p.h b/src/plugins/platforms/mirclient/qmirclientorientationchangeevent_p.h deleted file mode 100644 index 5abd3262dc..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientorientationchangeevent_p.h +++ /dev/null @@ -1,61 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef QMIRCLIENTORIENTATIONCHANGEEVENT_P_H -#define QMIRCLIENTORIENTATIONCHANGEEVENT_P_H - -#include <QEvent> -#include "qmirclientlogging.h" - -class OrientationChangeEvent : public QEvent { -public: - enum Orientation { TopUp, LeftUp, TopDown, RightUp }; - - OrientationChangeEvent(QEvent::Type type, Orientation orientation) - : QEvent(type) - , mOrientation(orientation) - { - } - - static const QEvent::Type mType; - Orientation mOrientation; -}; - -#endif // QMIRCLIENTORIENTATIONCHANGEEVENT_P_H diff --git a/src/plugins/platforms/mirclient/qmirclientplatformservices.cpp b/src/plugins/platforms/mirclient/qmirclientplatformservices.cpp deleted file mode 100644 index 1ccd57fc28..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientplatformservices.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#include "qmirclientplatformservices.h" - -#include <QUrl> - -#include <ubuntu/application/url_dispatcher/service.h> -#include <ubuntu/application/url_dispatcher/session.h> - -bool QMirClientPlatformServices::openUrl(const QUrl &url) -{ - return callDispatcher(url); -} - -bool QMirClientPlatformServices::openDocument(const QUrl &url) -{ - return callDispatcher(url); -} - -bool QMirClientPlatformServices::callDispatcher(const QUrl &url) -{ - UAUrlDispatcherSession* session = ua_url_dispatcher_session(); - if (!session) - return false; - - ua_url_dispatcher_session_open(session, url.toEncoded().constData(), NULL, NULL); - - free(session); - - // We are returning true here because the other option - // is spawning a nested event loop and wait for the - // callback. But there is no guarantee on how fast - // the callback is going to be so we prefer to avoid the - // nested event loop. Long term plan is improve Qt API - // to support an async openUrl - return true; -} diff --git a/src/plugins/platforms/mirclient/qmirclientplatformservices.h b/src/plugins/platforms/mirclient/qmirclientplatformservices.h deleted file mode 100644 index a1cd5758ca..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientplatformservices.h +++ /dev/null @@ -1,57 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef QMIRCLIENTPLATFORMSERVICES_H -#define QMIRCLIENTPLATFORMSERVICES_H - -#include <qpa/qplatformservices.h> -#include <QtFontDatabaseSupport/private/qgenericunixfontdatabase_p.h> -#include <QtEventDispatcherSupport/private/qgenericunixeventdispatcher_p.h> - -class QMirClientPlatformServices : public QPlatformServices { -public: - bool openUrl(const QUrl &url) override; - bool openDocument(const QUrl &url) override; - -private: - bool callDispatcher(const QUrl &url); -}; - -#endif // QMIRCLIENTPLATFORMSERVICES_H diff --git a/src/plugins/platforms/mirclient/qmirclientplugin.cpp b/src/plugins/platforms/mirclient/qmirclientplugin.cpp deleted file mode 100644 index fc44edfe40..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientplugin.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#include "qmirclientplugin.h" -#include "qmirclientintegration.h" -#include "qmirclientlogging.h" - -Q_LOGGING_CATEGORY(mirclient, "qt.qpa.mirclient", QtWarningMsg) - -QPlatformIntegration *QMirClientIntegrationPlugin::create(const QString &system, - const QStringList &/*paramList*/, - int &argc, char **argv) -{ - if (system.toLower() == QLatin1String("mirclient")) { - return new QMirClientClientIntegration(argc, argv); - } else { - return 0; - } -} diff --git a/src/plugins/platforms/mirclient/qmirclientscreen.cpp b/src/plugins/platforms/mirclient/qmirclientscreen.cpp deleted file mode 100644 index cc8db830aa..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientscreen.cpp +++ /dev/null @@ -1,262 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014-2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -// local -#include "qmirclientscreen.h" -#include "qmirclientlogging.h" -#include "qmirclientorientationchangeevent_p.h" -#include "qmirclientnativeinterface.h" - -#include <mir_toolkit/mir_client_library.h> - -// Qt -#include <QGuiApplication> -#include <QtCore/qmath.h> -#include <QScreen> -#include <QThread> -#include <qpa/qwindowsysteminterface.h> -#include <QtEglSupport/private/qeglconvenience_p.h> - -#include <memory> - -static const int overrideDevicePixelRatio = qgetenv("QT_DEVICE_PIXEL_RATIO").toInt(); - -static const char *orientationToStr(Qt::ScreenOrientation orientation) { - switch (orientation) { - case Qt::PrimaryOrientation: - return "primary"; - case Qt::PortraitOrientation: - return "portrait"; - case Qt::LandscapeOrientation: - return "landscape"; - case Qt::InvertedPortraitOrientation: - return "inverted portrait"; - case Qt::InvertedLandscapeOrientation: - return "inverted landscape"; - } - Q_UNREACHABLE(); -} - -const QEvent::Type OrientationChangeEvent::mType = - static_cast<QEvent::Type>(QEvent::registerEventType()); - - -QMirClientScreen::QMirClientScreen(const MirOutput *output, MirConnection *connection) - : mDevicePixelRatio(1.0) - , mFormat(QImage::Format_RGB32) - , mDepth(32) - , mDpi{0} - , mFormFactor{mir_form_factor_unknown} - , mScale{1.0} - , mOutputId(0) - , mCursor(connection) -{ - setMirOutput(output); -} - -QMirClientScreen::~QMirClientScreen() -{ -} - -void QMirClientScreen::customEvent(QEvent* event) { - Q_ASSERT(QThread::currentThread() == thread()); - - OrientationChangeEvent* oReadingEvent = static_cast<OrientationChangeEvent*>(event); - switch (oReadingEvent->mOrientation) { - case OrientationChangeEvent::LeftUp: { - mCurrentOrientation = (screen()->primaryOrientation() == Qt::LandscapeOrientation) ? - Qt::InvertedPortraitOrientation : Qt::LandscapeOrientation; - break; - } - case OrientationChangeEvent::TopUp: { - mCurrentOrientation = (screen()->primaryOrientation() == Qt::LandscapeOrientation) ? - Qt::LandscapeOrientation : Qt::PortraitOrientation; - break; - } - case OrientationChangeEvent::RightUp: { - mCurrentOrientation = (screen()->primaryOrientation() == Qt::LandscapeOrientation) ? - Qt::PortraitOrientation : Qt::InvertedLandscapeOrientation; - break; - } - case OrientationChangeEvent::TopDown: { - mCurrentOrientation = (screen()->primaryOrientation() == Qt::LandscapeOrientation) ? - Qt::InvertedLandscapeOrientation : Qt::InvertedPortraitOrientation; - break; - } - } - - // Raise the event signal so that client apps know the orientation changed - qCDebug(mirclient, "QMirClientScreen::customEvent - handling orientation change to %s", orientationToStr(mCurrentOrientation)); - QWindowSystemInterface::handleScreenOrientationChange(screen(), mCurrentOrientation); -} - -void QMirClientScreen::handleWindowSurfaceResize(int windowWidth, int windowHeight) -{ - if ((windowWidth > windowHeight && mGeometry.width() < mGeometry.height()) - || (windowWidth < windowHeight && mGeometry.width() > mGeometry.height())) { - - // The window aspect ratio differ's from the screen one. This means that - // unity8 has rotated the window in its scene. - // As there's no way to express window rotation in Qt's API, we have - // Flip QScreen's dimensions so that orientation properties match - // (primaryOrientation particularly). - // FIXME: This assumes a phone scenario. Won't work, or make sense, - // on the desktop - - QRect currGeometry = mGeometry; - mGeometry.setWidth(currGeometry.height()); - mGeometry.setHeight(currGeometry.width()); - - qCDebug(mirclient, "QMirClientScreen::handleWindowSurfaceResize - new screen geometry (w=%d, h=%d)", - mGeometry.width(), mGeometry.height()); - QWindowSystemInterface::handleScreenGeometryChange(screen(), - mGeometry /* newGeometry */, - mGeometry /* newAvailableGeometry */); - - if (mGeometry.width() < mGeometry.height()) { - mCurrentOrientation = Qt::PortraitOrientation; - } else { - mCurrentOrientation = Qt::LandscapeOrientation; - } - qCDebug(mirclient, "QMirClientScreen::handleWindowSurfaceResize - new orientation %s",orientationToStr(mCurrentOrientation)); - QWindowSystemInterface::handleScreenOrientationChange(screen(), mCurrentOrientation); - } -} - -void QMirClientScreen::setMirOutput(const MirOutput *output) -{ - // Physical screen size (in mm) - mPhysicalSize.setWidth(mir_output_get_physical_width_mm(output)); - mPhysicalSize.setHeight(mir_output_get_physical_height_mm(output)); - - // Pixel Format -// mFormat = qImageFormatFromMirPixelFormat(mir_output_get_current_pixel_format(output)); // GERRY: TODO - - // Pixel depth - mDepth = 8 * MIR_BYTES_PER_PIXEL(mir_output_get_current_pixel_format(output)); - - // Mode = Resolution & refresh rate - const MirOutputMode *mode = mir_output_get_current_mode(output); - mNativeGeometry.setX(mir_output_get_position_x(output)); - mNativeGeometry.setY(mir_output_get_position_y(output)); - mNativeGeometry.setWidth(mir_output_mode_get_width(mode)); - mNativeGeometry.setHeight(mir_output_mode_get_height(mode)); - - mRefreshRate = mir_output_mode_get_refresh_rate(mode); - - // UI scale & DPR - mScale = mir_output_get_scale_factor(output); - if (overrideDevicePixelRatio > 0) { - mDevicePixelRatio = overrideDevicePixelRatio; - } else { - mDevicePixelRatio = 1.0; // FIXME - need to determine suitable DPR for the specified scale - } - - mFormFactor = mir_output_get_form_factor(output); - - mOutputId = mir_output_get_id(output); - - mGeometry.setX(mNativeGeometry.x()); - mGeometry.setY(mNativeGeometry.y()); - mGeometry.setWidth(mNativeGeometry.width()); - mGeometry.setHeight(mNativeGeometry.height()); - - // Set the default orientation based on the initial screen dimensions. - mNativeOrientation = (mGeometry.width() >= mGeometry.height()) ? Qt::LandscapeOrientation : Qt::PortraitOrientation; - - // If it's a landscape device (i.e. some tablets), start in landscape, otherwise portrait - mCurrentOrientation = (mNativeOrientation == Qt::LandscapeOrientation) ? Qt::LandscapeOrientation : Qt::PortraitOrientation; -} - -void QMirClientScreen::updateMirOutput(const MirOutput *output) -{ - auto oldRefreshRate = mRefreshRate; - auto oldScale = mScale; - auto oldFormFactor = mFormFactor; - auto oldGeometry = mGeometry; - - setMirOutput(output); - - // Emit change signals in particular order - if (oldGeometry != mGeometry) { - QWindowSystemInterface::handleScreenGeometryChange(screen(), - mGeometry /* newGeometry */, - mGeometry /* newAvailableGeometry */); - } - - if (!qFuzzyCompare(mRefreshRate, oldRefreshRate)) { - QWindowSystemInterface::handleScreenRefreshRateChange(screen(), mRefreshRate); - } - - auto nativeInterface = static_cast<QMirClientNativeInterface *>(qGuiApp->platformNativeInterface()); - if (!qFuzzyCompare(mScale, oldScale)) { - nativeInterface->screenPropertyChanged(this, QStringLiteral("scale")); - } - if (mFormFactor != oldFormFactor) { - nativeInterface->screenPropertyChanged(this, QStringLiteral("formFactor")); - } -} - -void QMirClientScreen::setAdditionalMirDisplayProperties(float scale, MirFormFactor formFactor, int dpi) -{ - if (mDpi != dpi) { - mDpi = dpi; - QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(screen(), dpi, dpi); - } - - auto nativeInterface = static_cast<QMirClientNativeInterface *>(qGuiApp->platformNativeInterface()); - if (!qFuzzyCompare(mScale, scale)) { - mScale = scale; - nativeInterface->screenPropertyChanged(this, QStringLiteral("scale")); - } - if (mFormFactor != formFactor) { - mFormFactor = formFactor; - nativeInterface->screenPropertyChanged(this, QStringLiteral("formFactor")); - } -} - -QDpi QMirClientScreen::logicalDpi() const -{ - if (mDpi > 0) { - return QDpi(mDpi, mDpi); - } else { - return QPlatformScreen::logicalDpi(); - } -} diff --git a/src/plugins/platforms/mirclient/qmirclientscreen.h b/src/plugins/platforms/mirclient/qmirclientscreen.h deleted file mode 100644 index b31cba1964..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientscreen.h +++ /dev/null @@ -1,106 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014-2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef QMIRCLIENTSCREEN_H -#define QMIRCLIENTSCREEN_H - -#include <qpa/qplatformscreen.h> -#include <QSurfaceFormat> - -#include <mir_toolkit/common.h> // just for MirFormFactor enum - -#include "qmirclientcursor.h" - -struct MirConnection; -struct MirOutput; - -class QMirClientScreen : public QObject, public QPlatformScreen -{ - Q_OBJECT -public: - QMirClientScreen(const MirOutput *output, MirConnection *connection); - virtual ~QMirClientScreen(); - - // QPlatformScreen methods. - QImage::Format format() const override { return mFormat; } - int depth() const override { return mDepth; } - QRect geometry() const override { return mGeometry; } - QRect availableGeometry() const override { return mGeometry; } - QSizeF physicalSize() const override { return mPhysicalSize; } - qreal devicePixelRatio() const override { return mDevicePixelRatio; } - QDpi logicalDpi() const override; - Qt::ScreenOrientation nativeOrientation() const override { return mNativeOrientation; } - Qt::ScreenOrientation orientation() const override { return mNativeOrientation; } - QPlatformCursor *cursor() const override { return const_cast<QMirClientCursor*>(&mCursor); } - - // Additional Screen properties from Mir - int mirOutputId() const { return mOutputId; } - MirFormFactor formFactor() const { return mFormFactor; } - float scale() const { return mScale; } - - // Internally used methods - void updateMirOutput(const MirOutput *output); - void setAdditionalMirDisplayProperties(float scale, MirFormFactor formFactor, int dpi); - void handleWindowSurfaceResize(int width, int height); - - // QObject methods. - void customEvent(QEvent* event) override; - -private: - void setMirOutput(const MirOutput *output); - - QRect mGeometry, mNativeGeometry; - QSizeF mPhysicalSize; - qreal mDevicePixelRatio; - Qt::ScreenOrientation mNativeOrientation; - Qt::ScreenOrientation mCurrentOrientation; - QImage::Format mFormat; - int mDepth; - int mDpi; - qreal mRefreshRate; - MirFormFactor mFormFactor; - float mScale; - int mOutputId; - QMirClientCursor mCursor; - - friend class QMirClientNativeInterface; -}; - -#endif // QMIRCLIENTSCREEN_H diff --git a/src/plugins/platforms/mirclient/qmirclientscreenobserver.cpp b/src/plugins/platforms/mirclient/qmirclientscreenobserver.cpp deleted file mode 100644 index 792aeca351..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientscreenobserver.cpp +++ /dev/null @@ -1,161 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#include "qmirclientscreenobserver.h" -#include "qmirclientscreen.h" -#include "qmirclientwindow.h" -#include "qmirclientlogging.h" - -// Qt -#include <QMetaObject> -#include <QPointer> - -// Mir -#include <mirclient/mir_toolkit/mir_connection.h> -#include <mirclient/mir_toolkit/mir_display_configuration.h> - -#include <memory> - -namespace { - static void displayConfigurationChangedCallback(MirConnection */*connection*/, void* context) - { - ASSERT(context != NULL); - QMirClientScreenObserver *observer = static_cast<QMirClientScreenObserver *>(context); - QMetaObject::invokeMethod(observer, "update"); - } - - const char *mirFormFactorToStr(MirFormFactor formFactor) - { - switch (formFactor) { - case mir_form_factor_unknown: return "unknown"; - case mir_form_factor_phone: return "phone"; - case mir_form_factor_tablet: return "tablet"; - case mir_form_factor_monitor: return "monitor"; - case mir_form_factor_tv: return "tv"; - case mir_form_factor_projector: return "projector"; - } - Q_UNREACHABLE(); - } -} // anonymous namespace - -QMirClientScreenObserver::QMirClientScreenObserver(MirConnection *mirConnection) - : mMirConnection(mirConnection) -{ - mir_connection_set_display_config_change_callback(mirConnection, ::displayConfigurationChangedCallback, this); - update(); -} - -void QMirClientScreenObserver::update() -{ - // Wrap MirDisplayConfiguration to always delete when out of scope - auto configDeleter = [](MirDisplayConfig *config) { mir_display_config_release(config); }; - using configUp = std::unique_ptr<MirDisplayConfig, decltype(configDeleter)>; - configUp displayConfig(mir_connection_create_display_configuration(mMirConnection), configDeleter); - - // Mir only tells us something changed, it is up to us to figure out what. - QList<QMirClientScreen*> newScreenList; - QList<QMirClientScreen*> oldScreenList = mScreenList; - mScreenList.clear(); - - for (int i = 0; i < mir_display_config_get_num_outputs(displayConfig.get()); i++) { - const MirOutput *output = mir_display_config_get_output(displayConfig.get(), i); - if (mir_output_is_enabled(output)) { - QMirClientScreen *screen = findScreenWithId(oldScreenList, mir_output_get_id(output)); - if (screen) { // we've already set up this display before - screen->updateMirOutput(output); - oldScreenList.removeAll(screen); - } else { - // new display, so create QMirClientScreen for it - screen = new QMirClientScreen(output, mMirConnection); - newScreenList.append(screen); - qCDebug(mirclient) << "Added Screen with id" << mir_output_get_id(output) - << "and geometry" << screen->geometry(); - } - mScreenList.append(screen); - } - } - - // Announce old & unused Screens, should be deleted by the slot - Q_FOREACH (const auto screen, oldScreenList) { - Q_EMIT screenRemoved(screen); - } - - /* - * Mir's MirDisplayOutput does not include formFactor or scale for some reason, but Qt - * will want that information on creating the QScreen. Only way we get that info is when - * Mir positions a Window on that Screen. See "handleScreenPropertiesChange" method - */ - - // Announce new Screens - Q_FOREACH (const auto screen, newScreenList) { - Q_EMIT screenAdded(screen); - } - - qCDebug(mirclient) << "======================================="; - for (auto screen: mScreenList) { - qCDebug(mirclient) << screen << "- id:" << screen->mirOutputId() - << "geometry:" << screen->geometry() - << "form factor:" << mirFormFactorToStr(screen->formFactor()) - << "scale:" << screen->scale(); - } - qCDebug(mirclient) << "======================================="; -} - -QMirClientScreen *QMirClientScreenObserver::findScreenWithId(int id) -{ - return findScreenWithId(mScreenList, id); -} - -QMirClientScreen *QMirClientScreenObserver::findScreenWithId(const QList<QMirClientScreen *> &list, int id) -{ - Q_FOREACH (const auto screen, list) { - if (screen->mirOutputId() == id) { - return screen; - } - } - return nullptr; -} - -void QMirClientScreenObserver::handleScreenPropertiesChange(QMirClientScreen *screen, int dpi, - MirFormFactor formFactor, float scale) -{ - screen->setAdditionalMirDisplayProperties(scale, formFactor, dpi); -} - diff --git a/src/plugins/platforms/mirclient/qmirclientscreenobserver.h b/src/plugins/platforms/mirclient/qmirclientscreenobserver.h deleted file mode 100644 index ad927319c1..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientscreenobserver.h +++ /dev/null @@ -1,78 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef QMIRCLIENTSCREENOBSERVER_H -#define QMIRCLIENTSCREENOBSERVER_H - -#include <QObject> - -#include <mir_toolkit/mir_connection.h> - -class QMirClientScreen; - -class QMirClientScreenObserver : public QObject -{ - Q_OBJECT - -public: - QMirClientScreenObserver(MirConnection *connection); - - QList<QMirClientScreen*> screens() const { return mScreenList; } - QMirClientScreen *findScreenWithId(int id); - - void handleScreenPropertiesChange(QMirClientScreen *screen, int dpi, - MirFormFactor formFactor, float scale); - -Q_SIGNALS: - void screenAdded(QMirClientScreen *screen); - void screenRemoved(QMirClientScreen *screen); - -private Q_SLOTS: - void update(); - -private: - QMirClientScreen *findScreenWithId(const QList<QMirClientScreen *> &list, int id); - void removeScreen(QMirClientScreen *screen); - - MirConnection *mMirConnection; - QList<QMirClientScreen*> mScreenList; -}; - -#endif // QMIRCLIENTSCREENOBSERVER_H diff --git a/src/plugins/platforms/mirclient/qmirclienttheme.h b/src/plugins/platforms/mirclient/qmirclienttheme.h deleted file mode 100644 index 4bab1d0ee0..0000000000 --- a/src/plugins/platforms/mirclient/qmirclienttheme.h +++ /dev/null @@ -1,57 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef QMIRCLIENTTHEME_H -#define QMIRCLIENTTHEME_H - -#include <QtThemeSupport/private/qgenericunixthemes_p.h> - -class QMirClientTheme : public QGenericUnixTheme -{ -public: - static const char* name; - QMirClientTheme(); - virtual ~QMirClientTheme(); - - // From QPlatformTheme - QVariant themeHint(ThemeHint hint) const override; -}; - -#endif // QMIRCLIENTTHEME_H diff --git a/src/plugins/platforms/mirclient/qmirclientwindow.cpp b/src/plugins/platforms/mirclient/qmirclientwindow.cpp deleted file mode 100644 index decd21516e..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientwindow.cpp +++ /dev/null @@ -1,968 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014-2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -// Local -#include "qmirclientwindow.h" -#include "qmirclientdebugextension.h" -#include "qmirclientnativeinterface.h" -#include "qmirclientinput.h" -#include "qmirclientintegration.h" -#include "qmirclientscreen.h" -#include "qmirclientlogging.h" - -#include <mir_toolkit/mir_client_library.h> -#include <mir_toolkit/version.h> - -// Qt -#include <qpa/qwindowsysteminterface.h> -#include <QMutexLocker> -#include <QSize> -#include <QtMath> -#include <QtEglSupport/private/qeglconvenience_p.h> - -// Platform API -#include <ubuntu/application/instance.h> - -#include <EGL/egl.h> - -Q_LOGGING_CATEGORY(mirclientBufferSwap, "qt.qpa.mirclient.bufferSwap", QtWarningMsg) - -namespace -{ -const Qt::WindowType LowChromeWindowHint = (Qt::WindowType)0x00800000; - -// FIXME: this used to be defined by platform-api, but it's been removed in v3. Change ubuntu-keyboard to use -// a different enum for window roles. -enum UAUiWindowRole { - U_MAIN_ROLE = 1, - U_DASH_ROLE, - U_INDICATOR_ROLE, - U_NOTIFICATIONS_ROLE, - U_GREETER_ROLE, - U_LAUNCHER_ROLE, - U_ON_SCREEN_KEYBOARD_ROLE, - U_SHUTDOWN_DIALOG_ROLE, -}; - -struct MirSpecDeleter -{ - void operator()(MirSurfaceSpec *spec) { mir_surface_spec_release(spec); } -}; - -using Spec = std::unique_ptr<MirSurfaceSpec, MirSpecDeleter>; - -EGLNativeWindowType nativeWindowFor(MirSurface *surf) -{ - auto stream = mir_surface_get_buffer_stream(surf); - return reinterpret_cast<EGLNativeWindowType>(mir_buffer_stream_get_egl_native_window(stream)); -} - -const char *qtWindowStateToStr(Qt::WindowState state) -{ - switch (state) { - case Qt::WindowNoState: - return "NoState"; - case Qt::WindowFullScreen: - return "FullScreen"; - case Qt::WindowMaximized: - return "Maximized"; - case Qt::WindowMinimized: - return "Minimized"; - case Qt::WindowActive: - return "Active"; - } - Q_UNREACHABLE(); -} - -const char *mirSurfaceStateToStr(MirSurfaceState surfaceState) -{ - switch (surfaceState) { - case mir_surface_state_unknown: return "unknown"; - case mir_surface_state_restored: return "restored"; - case mir_surface_state_minimized: return "minimized"; - case mir_surface_state_maximized: return "vertmaximized"; - case mir_surface_state_vertmaximized: return "vertmaximized"; - case mir_surface_state_fullscreen: return "fullscreen"; - case mir_surface_state_horizmaximized: return "horizmaximized"; - case mir_surface_state_hidden: return "hidden"; - case mir_surface_states: Q_UNREACHABLE(); - } - Q_UNREACHABLE(); -} - -const char *mirPixelFormatToStr(MirPixelFormat pixelFormat) -{ - switch (pixelFormat) { - case mir_pixel_format_invalid: return "invalid"; - case mir_pixel_format_abgr_8888: return "ABGR8888"; - case mir_pixel_format_xbgr_8888: return "XBGR8888"; - case mir_pixel_format_argb_8888: return "ARGB8888"; - case mir_pixel_format_xrgb_8888: return "XRGB8888"; - case mir_pixel_format_bgr_888: return "BGR888"; - case mir_pixel_format_rgb_888: return "RGB888"; - case mir_pixel_format_rgb_565: return "RGB565"; - case mir_pixel_format_rgba_5551: return "RGBA5551"; - case mir_pixel_format_rgba_4444: return "RGBA4444"; - case mir_pixel_formats: Q_UNREACHABLE(); - } - Q_UNREACHABLE(); -} - -const char *mirSurfaceTypeToStr(MirSurfaceType type) -{ - switch (type) { - case mir_surface_type_normal: return "Normal"; /**< AKA "regular" */ - case mir_surface_type_utility: return "Utility"; /**< AKA "floating regular" */ - case mir_surface_type_dialog: return "Dialog"; - case mir_surface_type_gloss: return "Gloss"; - case mir_surface_type_freestyle: return "Freestyle"; - case mir_surface_type_menu: return "Menu"; - case mir_surface_type_inputmethod: return "Input Method"; /**< AKA "OSK" or handwriting etc. */ - case mir_surface_type_satellite: return "Satellite"; /**< AKA "toolbox"/"toolbar" */ - case mir_surface_type_tip: return "Tip"; /**< AKA "tooltip" */ - case mir_surface_types: Q_UNREACHABLE(); - } - return ""; -} - -MirSurfaceState qtWindowStateToMirSurfaceState(Qt::WindowState state) -{ - switch (state) { - case Qt::WindowNoState: - case Qt::WindowActive: - return mir_surface_state_restored; - case Qt::WindowFullScreen: - return mir_surface_state_fullscreen; - case Qt::WindowMaximized: - return mir_surface_state_maximized; - case Qt::WindowMinimized: - return mir_surface_state_minimized; - } - return mir_surface_state_unknown; // should never be reached -} - -MirSurfaceType qtWindowTypeToMirSurfaceType(Qt::WindowType type) -{ - switch (type & Qt::WindowType_Mask) { - case Qt::Dialog: - return mir_surface_type_dialog; - case Qt::Sheet: - case Qt::Drawer: - return mir_surface_type_utility; - case Qt::Popup: - case Qt::Tool: - return mir_surface_type_menu; - case Qt::ToolTip: - return mir_surface_type_tip; - case Qt::SplashScreen: - return mir_surface_type_freestyle; - case Qt::Window: - default: - return mir_surface_type_normal; - } -} - -WId makeId() -{ - static int id = 1; - return id++; -} - -UAUiWindowRole roleFor(QWindow *window) -{ - QVariant roleVariant = window->property("role"); - if (!roleVariant.isValid()) - return U_MAIN_ROLE; - - uint role = roleVariant.toUInt(); - if (role < U_MAIN_ROLE || role > U_SHUTDOWN_DIALOG_ROLE) - return U_MAIN_ROLE; - - return static_cast<UAUiWindowRole>(role); -} - -QMirClientWindow *transientParentFor(QWindow *window) -{ - QWindow *parent = window->transientParent(); - return parent ? static_cast<QMirClientWindow *>(parent->handle()) : nullptr; -} - -bool requiresParent(const MirSurfaceType type) -{ - switch (type) { - case mir_surface_type_dialog: //FIXME - not quite what the specification dictates, but is what Mir's api dictates - case mir_surface_type_utility: - case mir_surface_type_gloss: - case mir_surface_type_menu: - case mir_surface_type_satellite: - case mir_surface_type_tip: - return true; - default: - return false; - } -} - -bool requiresParent(const Qt::WindowType type) -{ - return requiresParent(qtWindowTypeToMirSurfaceType(type)); -} - -bool isMovable(const Qt::WindowType type) -{ - auto mirType = qtWindowTypeToMirSurfaceType(type); - switch (mirType) { - case mir_surface_type_menu: - case mir_surface_type_tip: - return true; - default: - return false; - } -} - -Spec makeSurfaceSpec(QWindow *window, MirPixelFormat pixelFormat, QMirClientWindow *parentWindowHandle, - MirConnection *connection) -{ - const auto geometry = window->geometry(); - const int width = geometry.width() > 0 ? geometry.width() : 1; - const int height = geometry.height() > 0 ? geometry.height() : 1; - auto type = qtWindowTypeToMirSurfaceType(window->type()); - - if (U_ON_SCREEN_KEYBOARD_ROLE == roleFor(window)) { - type = mir_surface_type_inputmethod; - } - - MirRectangle location{geometry.x(), geometry.y(), 0, 0}; - MirSurface *parent = nullptr; - if (parentWindowHandle) { - parent = parentWindowHandle->mirSurface(); - // Qt uses absolute positioning, but Mir positions surfaces relative to parent. - location.top -= parentWindowHandle->geometry().top(); - location.left -= parentWindowHandle->geometry().left(); - } - - Spec spec; - - switch (type) { - case mir_surface_type_menu: - spec = Spec{mir_connection_create_spec_for_menu(connection, width, height, pixelFormat, parent, - &location, mir_edge_attachment_any)}; - break; - case mir_surface_type_dialog: - spec = Spec{mir_connection_create_spec_for_modal_dialog(connection, width, height, pixelFormat, parent)}; - break; - case mir_surface_type_utility: - spec = Spec{mir_connection_create_spec_for_dialog(connection, width, height, pixelFormat)}; - break; - case mir_surface_type_tip: -#if MIR_CLIENT_VERSION < MIR_VERSION_NUMBER(3, 4, 0) - spec = Spec{mir_connection_create_spec_for_tooltip(connection, width, height, pixelFormat, parent, - &location)}; -#else - spec = Spec{mir_connection_create_spec_for_tip(connection, width, height, pixelFormat, parent, - &location, mir_edge_attachment_any)}; -#endif - break; - case mir_surface_type_inputmethod: - spec = Spec{mir_connection_create_spec_for_input_method(connection, width, height, pixelFormat)}; - break; - default: - spec = Spec{mir_connection_create_spec_for_normal_surface(connection, width, height, pixelFormat)}; - break; - } - - qCDebug(mirclient, "makeSurfaceSpec(window=%p): %s spec (type=0x%x, position=(%d, %d)px, size=(%dx%d)px)", - window, mirSurfaceTypeToStr(type), window->type(), location.left, location.top, width, height); - - return std::move(spec); -} - -void setSizingConstraints(MirSurfaceSpec *spec, const QSize& minSize, const QSize& maxSize, const QSize& increment) -{ - mir_surface_spec_set_min_width(spec, minSize.width()); - mir_surface_spec_set_min_height(spec, minSize.height()); - if (maxSize.width() >= minSize.width()) { - mir_surface_spec_set_max_width(spec, maxSize.width()); - } - if (maxSize.height() >= minSize.height()) { - mir_surface_spec_set_max_height(spec, maxSize.height()); - } - if (increment.width() > 0) { - mir_surface_spec_set_width_increment(spec, increment.width()); - } - if (increment.height() > 0) { - mir_surface_spec_set_height_increment(spec, increment.height()); - } -} - -MirSurface *createMirSurface(QWindow *window, int mirOutputId, QMirClientWindow *parentWindowHandle, - MirPixelFormat pixelFormat, MirConnection *connection, - mir_surface_event_callback inputCallback, void *inputContext) -{ - auto spec = makeSurfaceSpec(window, pixelFormat, parentWindowHandle, connection); - - // Install event handler as early as possible - mir_surface_spec_set_event_handler(spec.get(), inputCallback, inputContext); - - const auto title = window->title().toUtf8(); - mir_surface_spec_set_name(spec.get(), title.constData()); - - setSizingConstraints(spec.get(), window->minimumSize(), window->maximumSize(), window->sizeIncrement()); - - if (window->windowState() == Qt::WindowFullScreen) { - mir_surface_spec_set_fullscreen_on_output(spec.get(), mirOutputId); - } - - if (window->flags() & LowChromeWindowHint) { - mir_surface_spec_set_shell_chrome(spec.get(), mir_shell_chrome_low); - } - - if (!window->isVisible()) { - mir_surface_spec_set_state(spec.get(), mir_surface_state_hidden); - } - - auto surface = mir_surface_create_sync(spec.get()); - Q_ASSERT(mir_surface_is_valid(surface)); - return surface; -} - -QMirClientWindow *getParentIfNecessary(QWindow *window, QMirClientInput *input) -{ - QMirClientWindow *parentWindowHandle = nullptr; - if (requiresParent(window->type())) { - parentWindowHandle = transientParentFor(window); - if (parentWindowHandle == nullptr) { - // NOTE: Mir requires this surface have a parent. Try using the last surface to receive input as that will - // most likely be the one that caused this surface to be created - parentWindowHandle = input->lastInputWindow(); - } - } - return parentWindowHandle; -} - -MirPixelFormat disableAlphaBufferIfPossible(MirPixelFormat pixelFormat) -{ - switch (pixelFormat) { - case mir_pixel_format_abgr_8888: - return mir_pixel_format_xbgr_8888; - case mir_pixel_format_argb_8888: - return mir_pixel_format_xrgb_8888; - default: // can do nothing, leave it alone - return pixelFormat; - } -} -} //namespace - - - -class UbuntuSurface -{ -public: - UbuntuSurface(QMirClientWindow *platformWindow, EGLDisplay display, QMirClientInput *input, MirConnection *connection); - ~UbuntuSurface(); - - UbuntuSurface(const UbuntuSurface &) = delete; - UbuntuSurface& operator=(const UbuntuSurface &) = delete; - - void updateGeometry(const QRect &newGeometry); - void updateTitle(const QString& title); - void setSizingConstraints(const QSize& minSize, const QSize& maxSize, const QSize& increment); - - void onSwapBuffersDone(); - void handleSurfaceResized(int width, int height); - int needsRepaint() const; - - MirSurfaceState state() const { return mir_surface_get_state(mMirSurface); } - void setState(MirSurfaceState state); - - MirSurfaceType type() const { return mir_surface_get_type(mMirSurface); } - - void setShellChrome(MirShellChrome shellChrome); - - EGLSurface eglSurface() const { return mEglSurface; } - MirSurface *mirSurface() const { return mMirSurface; } - - void setSurfaceParent(MirSurface*); - bool hasParent() const { return mParented; } - - QSurfaceFormat format() const { return mFormat; } - - bool mNeedsExposeCatchup; - - QString persistentSurfaceId(); - -private: - static void surfaceEventCallback(MirSurface* surface, const MirEvent *event, void* context); - void postEvent(const MirEvent *event); - - QWindow * const mWindow; - QMirClientWindow * const mPlatformWindow; - QMirClientInput * const mInput; - MirConnection * const mConnection; - QMirClientWindow * mParentWindowHandle{nullptr}; - - MirSurface* mMirSurface; - const EGLDisplay mEglDisplay; - EGLSurface mEglSurface; - - bool mNeedsRepaint; - bool mParented; - QSize mBufferSize; - QSurfaceFormat mFormat; - MirPixelFormat mPixelFormat; - - QMutex mTargetSizeMutex; - QSize mTargetSize; - MirShellChrome mShellChrome; - QString mPersistentIdStr; -}; - -UbuntuSurface::UbuntuSurface(QMirClientWindow *platformWindow, EGLDisplay display, QMirClientInput *input, MirConnection *connection) - : mWindow(platformWindow->window()) - , mPlatformWindow(platformWindow) - , mInput(input) - , mConnection(connection) - , mEglDisplay(display) - , mNeedsRepaint(false) - , mParented(mWindow->transientParent() || mWindow->parent()) - , mFormat(mWindow->requestedFormat()) - , mShellChrome(mWindow->flags() & LowChromeWindowHint ? mir_shell_chrome_low : mir_shell_chrome_normal) -{ - // Have Qt choose most suitable EGLConfig for the requested surface format, and update format to reflect it - EGLConfig config = q_configFromGLFormat(display, mFormat, true); - if (config == 0) { - // Older Intel Atom-based devices only support OpenGL 1.4 compatibility profile but by default - // QML asks for at least OpenGL 2.0. The XCB GLX backend ignores this request and returns a - // 1.4 context, but the XCB EGL backend tries to honor it, and fails. The 1.4 context appears to - // have sufficient capabilities on MESA (i915) to render correctly however. So reduce the default - // requested OpenGL version to 1.0 to ensure EGL will give us a working context (lp:1549455). - static const bool isMesa = QString(eglQueryString(display, EGL_VENDOR)).contains(QStringLiteral("Mesa")); - if (isMesa) { - qCDebug(mirclientGraphics, "Attempting to choose OpenGL 1.4 context which may suit Mesa"); - mFormat.setMajorVersion(1); - mFormat.setMinorVersion(4); - config = q_configFromGLFormat(display, mFormat, true); - } - } - if (config == 0) { - qCritical() << "Qt failed to choose a suitable EGLConfig to suit the surface format" << mFormat; - } - - mFormat = q_glFormatFromConfig(display, config, mFormat); - - // Have Mir decide the pixel format most suited to the chosen EGLConfig. This is the only way - // Mir will know what EGLConfig has been chosen - it cannot deduce it from the buffers. - mPixelFormat = mir_connection_get_egl_pixel_format(connection, display, config); - // But the chosen EGLConfig might have an alpha buffer enabled, even if not requested by the client. - // If that's the case, try to edit the chosen pixel format in order to disable the alpha buffer. - // This is an optimization for the compositor, as it can avoid blending this surface. - if (mWindow->requestedFormat().alphaBufferSize() < 0) { - mPixelFormat = disableAlphaBufferIfPossible(mPixelFormat); - } - - const auto outputId = static_cast<QMirClientScreen *>(mWindow->screen()->handle())->mirOutputId(); - - mParentWindowHandle = getParentIfNecessary(mWindow, input); - - mMirSurface = createMirSurface(mWindow, outputId, mParentWindowHandle, mPixelFormat, connection, surfaceEventCallback, this); - mEglSurface = eglCreateWindowSurface(mEglDisplay, config, nativeWindowFor(mMirSurface), nullptr); - - mNeedsExposeCatchup = mir_surface_get_visibility(mMirSurface) == mir_surface_visibility_occluded; - - // Window manager can give us a final size different from what we asked for - // so let's check what we ended up getting - MirSurfaceParameters parameters; - mir_surface_get_parameters(mMirSurface, ¶meters); - - auto geom = mWindow->geometry(); - geom.setWidth(parameters.width); - geom.setHeight(parameters.height); - - // Assume that the buffer size matches the surface size at creation time - mBufferSize = geom.size(); - QWindowSystemInterface::handleGeometryChange(mWindow, geom); - - qCDebug(mirclient) << "Created surface with geometry:" << geom << "title:" << mWindow->title() - << "role:" << roleFor(mWindow); - qCDebug(mirclientGraphics) - << "Requested format:" << mWindow->requestedFormat() - << "\nActual format:" << mFormat - << "with associated Mir pixel format:" << mirPixelFormatToStr(mPixelFormat); -} - -UbuntuSurface::~UbuntuSurface() -{ - if (mEglSurface != EGL_NO_SURFACE) - eglDestroySurface(mEglDisplay, mEglSurface); - if (mMirSurface) { - mir_surface_release_sync(mMirSurface); - } -} - -void UbuntuSurface::updateGeometry(const QRect &newGeometry) -{ - qCDebug(mirclient,"updateGeometry(window=%p, width=%d, height=%d)", mWindow, - newGeometry.width(), newGeometry.height()); - - Spec spec; - if (isMovable(mWindow->type())) { - spec = Spec{makeSurfaceSpec(mWindow, mPixelFormat, mParentWindowHandle, mConnection)}; - } else { - spec = Spec{mir_connection_create_spec_for_changes(mConnection)}; - mir_surface_spec_set_width(spec.get(), newGeometry.width()); - mir_surface_spec_set_height(spec.get(), newGeometry.height()); - } - mir_surface_apply_spec(mMirSurface, spec.get()); -} - -void UbuntuSurface::updateTitle(const QString& newTitle) -{ - const auto title = newTitle.toUtf8(); - Spec spec{mir_connection_create_spec_for_changes(mConnection)}; - mir_surface_spec_set_name(spec.get(), title.constData()); - mir_surface_apply_spec(mMirSurface, spec.get()); -} - -void UbuntuSurface::setSizingConstraints(const QSize& minSize, const QSize& maxSize, const QSize& increment) -{ - Spec spec{mir_connection_create_spec_for_changes(mConnection)}; - ::setSizingConstraints(spec.get(), minSize, maxSize, increment); - mir_surface_apply_spec(mMirSurface, spec.get()); -} - -void UbuntuSurface::handleSurfaceResized(int width, int height) -{ - QMutexLocker lock(&mTargetSizeMutex); - - // mir's resize event is mainly a signal that we need to redraw our content. We use the - // width/height as identifiers to figure out if this is the latest surface resize event - // that has posted, discarding any old ones. This avoids issuing too many redraw events. - // see TODO in postEvent as the ideal way we should handle this. - // The actual buffer size may or may have not changed at this point, so let the rendering - // thread drive the window geometry updates. - mNeedsRepaint = mTargetSize.width() == width && mTargetSize.height() == height; -} - -int UbuntuSurface::needsRepaint() const -{ - if (mNeedsRepaint) { - if (mTargetSize != mBufferSize) { - //If the buffer hasn't changed yet, we need at least two redraws, - //once to get the new buffer size and propagate the geometry changes - //and the second to redraw the content at the new size - return 2; - } else { - // The buffer size has already been updated so we only need one redraw - // to render at the new size - return 1; - } - } - return 0; -} - -void UbuntuSurface::setState(MirSurfaceState state) -{ - mir_wait_for(mir_surface_set_state(mMirSurface, state)); -} - -void UbuntuSurface::setShellChrome(MirShellChrome chrome) -{ - if (chrome != mShellChrome) { - auto spec = Spec{mir_connection_create_spec_for_changes(mConnection)}; - mir_surface_spec_set_shell_chrome(spec.get(), chrome); - mir_surface_apply_spec(mMirSurface, spec.get()); - - mShellChrome = chrome; - } -} - -void UbuntuSurface::onSwapBuffersDone() -{ - static int sFrameNumber = 0; - ++sFrameNumber; - - EGLint eglSurfaceWidth = -1; - EGLint eglSurfaceHeight = -1; - eglQuerySurface(mEglDisplay, mEglSurface, EGL_WIDTH, &eglSurfaceWidth); - eglQuerySurface(mEglDisplay, mEglSurface, EGL_HEIGHT, &eglSurfaceHeight); - - const bool validSize = eglSurfaceWidth > 0 && eglSurfaceHeight > 0; - - if (validSize && (mBufferSize.width() != eglSurfaceWidth || mBufferSize.height() != eglSurfaceHeight)) { - - qCDebug(mirclientBufferSwap, "onSwapBuffersDone(window=%p) [%d] - size changed (%d, %d) => (%d, %d)", - mWindow, sFrameNumber, mBufferSize.width(), mBufferSize.height(), eglSurfaceWidth, eglSurfaceHeight); - - mBufferSize.rwidth() = eglSurfaceWidth; - mBufferSize.rheight() = eglSurfaceHeight; - - QRect newGeometry = mPlatformWindow->geometry(); - newGeometry.setSize(mBufferSize); - - QWindowSystemInterface::handleGeometryChange(mWindow, newGeometry); - } else { - qCDebug(mirclientBufferSwap, "onSwapBuffersDone(window=%p) [%d] - buffer size (%d,%d)", - mWindow, sFrameNumber, mBufferSize.width(), mBufferSize.height()); - } -} - -void UbuntuSurface::surfaceEventCallback(MirSurface *surface, const MirEvent *event, void* context) -{ - Q_UNUSED(surface); - Q_ASSERT(context != nullptr); - - auto s = static_cast<UbuntuSurface *>(context); - s->postEvent(event); -} - -void UbuntuSurface::postEvent(const MirEvent *event) -{ - if (mir_event_type_resize == mir_event_get_type(event)) { - // TODO: The current event queue just accumulates all resize events; - // It would be nicer if we could update just one event if that event has not been dispatched. - // As a workaround, we use the width/height as an identifier of this latest event - // so the event handler (handleSurfaceResized) can discard/ignore old ones. - const auto resizeEvent = mir_event_get_resize_event(event); - const auto width = mir_resize_event_get_width(resizeEvent); - const auto height = mir_resize_event_get_height(resizeEvent); - qCDebug(mirclient, "resizeEvent(window=%p, width=%d, height=%d)", mWindow, width, height); - - QMutexLocker lock(&mTargetSizeMutex); - mTargetSize.rwidth() = width; - mTargetSize.rheight() = height; - } - - mInput->postEvent(mPlatformWindow, event); -} - -void UbuntuSurface::setSurfaceParent(MirSurface* parent) -{ - qCDebug(mirclient, "setSurfaceParent(window=%p)", mWindow); - - mParented = true; - Spec spec{mir_connection_create_spec_for_changes(mConnection)}; - mir_surface_spec_set_parent(spec.get(), parent); - mir_surface_apply_spec(mMirSurface, spec.get()); -} - -QString UbuntuSurface::persistentSurfaceId() -{ - if (mPersistentIdStr.isEmpty()) { - MirPersistentId* mirPermaId = mir_surface_request_persistent_id_sync(mMirSurface); - mPersistentIdStr = mir_persistent_id_as_string(mirPermaId); - mir_persistent_id_release(mirPermaId); - } - return mPersistentIdStr; -} - -QMirClientWindow::QMirClientWindow(QWindow *w, QMirClientInput *input, QMirClientNativeInterface *native, - QMirClientAppStateController *appState, EGLDisplay eglDisplay, - MirConnection *mirConnection, QMirClientDebugExtension *debugExt) - : QObject(nullptr) - , QPlatformWindow(w) - , mId(makeId()) - , mWindowState(w->windowState()) - , mWindowFlags(w->flags()) - , mWindowVisible(false) - , mAppStateController(appState) - , mDebugExtention(debugExt) - , mNativeInterface(native) - , mSurface(new UbuntuSurface{this, eglDisplay, input, mirConnection}) - , mScale(1.0) - , mFormFactor(mir_form_factor_unknown) -{ - mWindowExposed = mSurface->mNeedsExposeCatchup == false; - - qCDebug(mirclient, "QMirClientWindow(window=%p, screen=%p, input=%p, surf=%p) with title '%s', role: '%d'", - w, w->screen()->handle(), input, mSurface.get(), qPrintable(window()->title()), roleFor(window())); -} - -QMirClientWindow::~QMirClientWindow() -{ - qCDebug(mirclient, "~QMirClientWindow(window=%p)", this); -} - -void QMirClientWindow::handleSurfaceResized(int width, int height) -{ - QMutexLocker lock(&mMutex); - qCDebug(mirclient, "handleSurfaceResize(window=%p, size=(%dx%d)px", window(), width, height); - - mSurface->handleSurfaceResized(width, height); - - // This resize event could have occurred just after the last buffer swap for this window. - // This means the client may still be holding a buffer with the older size. The first redraw call - // will then render at the old size. After swapping the client now will get a new buffer with the - // updated size but it still needs re-rendering so another redraw may be needed. - // A mir API to drop the currently held buffer would help here, so that we wouldn't have to redraw twice - auto const numRepaints = mSurface->needsRepaint(); - lock.unlock(); - qCDebug(mirclient, "handleSurfaceResize(window=%p) redraw %d times", window(), numRepaints); - for (int i = 0; i < numRepaints; i++) { - qCDebug(mirclient, "handleSurfaceResize(window=%p) repainting size=(%dx%d)dp", window(), geometry().size().width(), geometry().size().height()); - QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size())); - } -} - -void QMirClientWindow::handleSurfaceExposeChange(bool exposed) -{ - QMutexLocker lock(&mMutex); - qCDebug(mirclient, "handleSurfaceExposeChange(window=%p, exposed=%s)", window(), exposed ? "true" : "false"); - - mSurface->mNeedsExposeCatchup = false; - if (mWindowExposed == exposed) return; - mWindowExposed = exposed; - - lock.unlock(); - QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size())); -} - -void QMirClientWindow::handleSurfaceFocusChanged(bool focused) -{ - qCDebug(mirclient, "handleSurfaceFocusChanged(window=%p, focused=%d)", window(), focused); - if (focused) { - mAppStateController->setWindowFocused(true); - QWindowSystemInterface::handleWindowActivated(window(), Qt::ActiveWindowFocusReason); - } else { - mAppStateController->setWindowFocused(false); - } -} - -void QMirClientWindow::handleSurfaceVisibilityChanged(bool visible) -{ - qCDebug(mirclient, "handleSurfaceVisibilityChanged(window=%p, visible=%d)", window(), visible); - - if (mWindowVisible == visible) return; - mWindowVisible = visible; - - QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size())); -} - -void QMirClientWindow::handleSurfaceStateChanged(Qt::WindowState state) -{ - qCDebug(mirclient, "handleSurfaceStateChanged(window=%p, %s)", window(), qtWindowStateToStr(state)); - - if (mWindowState == state) return; - mWindowState = state; - - QWindowSystemInterface::handleWindowStateChanged(window(), state); -} - -void QMirClientWindow::setWindowState(Qt::WindowStates states) -{ - Qt::WindowState state = Qt::WindowNoState; - if (states & Qt::WindowMinimized) - state = Qt::WindowMinimized; - else if (states & Qt::WindowFullScreen) - state = Qt::WindowFullScreen; - else if (states & Qt::WindowMaximized) - state = Qt::WindowMaximized; - - QMutexLocker lock(&mMutex); - qCDebug(mirclient, "setWindowState(window=%p, %s)", this, qtWindowStateToStr(state)); - - if (mWindowState == state) return; - mWindowState = state; - - lock.unlock(); - updateSurfaceState(); -} - -void QMirClientWindow::setWindowFlags(Qt::WindowFlags flags) -{ - QMutexLocker lock(&mMutex); - qCDebug(mirclient, "setWindowFlags(window=%p, 0x%x)", this, (int)flags); - - if (mWindowFlags == flags) return; - mWindowFlags = flags; - - mSurface->setShellChrome(mWindowFlags & LowChromeWindowHint ? mir_shell_chrome_low : mir_shell_chrome_normal); -} - -QRect QMirClientWindow::geometry() const -{ - if (mDebugExtention) { - auto geom = QPlatformWindow::geometry(); - geom.moveTopLeft(mDebugExtention->mapSurfacePointToScreen(mSurface->mirSurface(), QPoint(0,0))); - return geom; - } else { - return QPlatformWindow::geometry(); - } -} - -void QMirClientWindow::setGeometry(const QRect& rect) -{ - QMutexLocker lock(&mMutex); - - if (window()->windowState() == Qt::WindowFullScreen || window()->windowState() == Qt::WindowMaximized) { - qCDebug(mirclient, "setGeometry(window=%p) - not resizing, window is maximized or fullscreen", window()); - return; - } - - qCDebug(mirclient, "setGeometry (window=%p, position=(%d, %d)dp, size=(%dx%d)dp)", - window(), rect.x(), rect.y(), rect.width(), rect.height()); - // Immediately update internal geometry so Qt believes position updated - QRect newPosition(geometry()); - newPosition.moveTo(rect.topLeft()); - QPlatformWindow::setGeometry(newPosition); - - mSurface->updateGeometry(rect); - // Note: don't call handleGeometryChange here, wait to see what Mir replies with. -} - -void QMirClientWindow::setVisible(bool visible) -{ - QMutexLocker lock(&mMutex); - qCDebug(mirclient, "setVisible (window=%p, visible=%s)", window(), visible ? "true" : "false"); - - if (mWindowVisible == visible) return; - mWindowVisible = visible; - - if (visible) { - if (!mSurface->hasParent() && window()->type() == Qt::Dialog) { - // The dialog may have been parented after creation time - // so morph it into a modal dialog - auto parent = transientParentFor(window()); - if (parent) { - mSurface->setSurfaceParent(parent->mirSurface()); - } - } - } - - lock.unlock(); - updateSurfaceState(); - QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size())); -} - -void QMirClientWindow::setWindowTitle(const QString& title) -{ - QMutexLocker lock(&mMutex); - qCDebug(mirclient, "setWindowTitle(window=%p) title=%s)", window(), title.toUtf8().constData()); - mSurface->updateTitle(title); -} - -void QMirClientWindow::propagateSizeHints() -{ - QMutexLocker lock(&mMutex); - const auto win = window(); - qCDebug(mirclient, "propagateSizeHints(window=%p) min(%d,%d), max(%d,%d) increment(%d, %d)", - win, win->minimumSize().width(), win->minimumSize().height(), - win->maximumSize().width(), win->maximumSize().height(), - win->sizeIncrement().width(), win->sizeIncrement().height()); - mSurface->setSizingConstraints(win->minimumSize(), win->maximumSize(), win->sizeIncrement()); -} - -bool QMirClientWindow::isExposed() const -{ - // mNeedsExposeCatchup because we need to render a frame to get the expose surface event from mir. - return mWindowVisible && (mWindowExposed || (mSurface && mSurface->mNeedsExposeCatchup)); -} - -QSurfaceFormat QMirClientWindow::format() const -{ - return mSurface->format(); -} - -QPoint QMirClientWindow::mapToGlobal(const QPoint &pos) const -{ - if (mDebugExtention) { - return mDebugExtention->mapSurfacePointToScreen(mSurface->mirSurface(), pos); - } else { - return pos; - } -} - -void* QMirClientWindow::eglSurface() const -{ - return mSurface->eglSurface(); -} - -MirSurface *QMirClientWindow::mirSurface() const -{ - return mSurface->mirSurface(); -} - -WId QMirClientWindow::winId() const -{ - return mId; -} - -void QMirClientWindow::onSwapBuffersDone() -{ - QMutexLocker lock(&mMutex); - mSurface->onSwapBuffersDone(); - - if (mSurface->mNeedsExposeCatchup) { - mSurface->mNeedsExposeCatchup = false; - mWindowExposed = false; - - lock.unlock(); - QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size())); - } -} - -void QMirClientWindow::handleScreenPropertiesChange(MirFormFactor formFactor, float scale) -{ - // Update the scale & form factor native-interface properties for the windows affected - // as there is no convenient way to emit signals for those custom properties on a QScreen - if (formFactor != mFormFactor) { - mFormFactor = formFactor; - Q_EMIT mNativeInterface->windowPropertyChanged(this, QStringLiteral("formFactor")); - } - - if (!qFuzzyCompare(scale, mScale)) { - mScale = scale; - Q_EMIT mNativeInterface->windowPropertyChanged(this, QStringLiteral("scale")); - } -} - -void QMirClientWindow::updateSurfaceState() -{ - QMutexLocker lock(&mMutex); - MirSurfaceState newState = mWindowVisible ? qtWindowStateToMirSurfaceState(mWindowState) : - mir_surface_state_hidden; - qCDebug(mirclient, "updateSurfaceState (window=%p, surfaceState=%s)", window(), mirSurfaceStateToStr(newState)); - if (newState != mSurface->state()) { - mSurface->setState(newState); - } -} - -QString QMirClientWindow::persistentSurfaceId() -{ - return mSurface->persistentSurfaceId(); -} diff --git a/src/plugins/platforms/mirclient/qmirclientwindow.h b/src/plugins/platforms/mirclient/qmirclientwindow.h deleted file mode 100644 index 6c5695d62f..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientwindow.h +++ /dev/null @@ -1,118 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014-2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef QMIRCLIENTWINDOW_H -#define QMIRCLIENTWINDOW_H - -#include <qpa/qplatformwindow.h> -#include <QSharedPointer> -#include <QMutex> - -#include <mir_toolkit/common.h> // needed only for MirFormFactor enum - -#include <memory> - -#include <EGL/egl.h> - -class QMirClientAppStateController; -class QMirClientDebugExtension; -class QMirClientNativeInterface; -class QMirClientInput; -class QMirClientScreen; -class UbuntuSurface; -struct MirSurface; -class MirConnection; - -class QMirClientWindow : public QObject, public QPlatformWindow -{ - Q_OBJECT -public: - QMirClientWindow(QWindow *w, QMirClientInput *input, QMirClientNativeInterface* native, - QMirClientAppStateController *appState, EGLDisplay eglDisplay, - MirConnection *mirConnection, QMirClientDebugExtension *debugExt); - virtual ~QMirClientWindow(); - - // QPlatformWindow methods. - WId winId() const override; - QRect geometry() const override; - void setGeometry(const QRect&) override; - void setWindowState(Qt::WindowStates state) override; - void setWindowFlags(Qt::WindowFlags flags) override; - void setVisible(bool visible) override; - void setWindowTitle(const QString &title) override; - void propagateSizeHints() override; - bool isExposed() const override; - - QPoint mapToGlobal(const QPoint &pos) const override; - QSurfaceFormat format() const override; - - // Additional Window properties exposed by NativeInterface - MirFormFactor formFactor() const { return mFormFactor; } - float scale() const { return mScale; } - - // New methods. - void *eglSurface() const; - MirSurface *mirSurface() const; - void handleSurfaceResized(int width, int height); - void handleSurfaceExposeChange(bool exposed); - void handleSurfaceFocusChanged(bool focused); - void handleSurfaceVisibilityChanged(bool visible); - void handleSurfaceStateChanged(Qt::WindowState state); - void onSwapBuffersDone(); - void handleScreenPropertiesChange(MirFormFactor formFactor, float scale); - QString persistentSurfaceId(); - -private: - void updateSurfaceState(); - mutable QMutex mMutex; - const WId mId; - Qt::WindowState mWindowState; - Qt::WindowFlags mWindowFlags; - bool mWindowVisible; - bool mWindowExposed; - QMirClientAppStateController *mAppStateController; - QMirClientDebugExtension *mDebugExtention; - QMirClientNativeInterface *mNativeInterface; - std::unique_ptr<UbuntuSurface> mSurface; - float mScale; - MirFormFactor mFormFactor; -}; - -#endif // QMIRCLIENTWINDOW_H diff --git a/src/plugins/platforms/offscreen/qoffscreencommon.cpp b/src/plugins/platforms/offscreen/qoffscreencommon.cpp index f0eb69718a..eae25012c1 100644 --- a/src/plugins/platforms/offscreen/qoffscreencommon.cpp +++ b/src/plugins/platforms/offscreen/qoffscreencommon.cpp @@ -77,7 +77,8 @@ public: if (containing != previous) QWindowSystemInterface::handleEnterLeaveEvent(containing, previous, local, pos); - QWindowSystemInterface::handleMouseEvent(containing, local, pos, QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers()); + QWindowSystemInterface::handleMouseEvent(containing, local, pos, QGuiApplication::mouseButtons(), Qt::NoButton, + QEvent::MouseMove, QGuiApplication::keyboardModifiers(), Qt::MouseEventSynthesizedByQt); QOffscreenScreen::windowContainingCursor = containing ? containing->handle() : 0; } diff --git a/src/plugins/platforms/openwfd/qopenwfdscreen.h b/src/plugins/platforms/openwfd/qopenwfdscreen.h index dede0025a9..dec51d306b 100644 --- a/src/plugins/platforms/openwfd/qopenwfdscreen.h +++ b/src/plugins/platforms/openwfd/qopenwfdscreen.h @@ -48,7 +48,6 @@ #include <WF/wfd.h> #include <QtCore/QVarLengthArray> -#include <QtCore/QLinkedList> #define BUFFER_NUM 4 diff --git a/src/plugins/platforms/platforms.pro b/src/plugins/platforms/platforms.pro index acc55adf6f..c4f2b30965 100644 --- a/src/plugins/platforms/platforms.pro +++ b/src/plugins/platforms/platforms.pro @@ -48,6 +48,4 @@ haiku { wasm: SUBDIRS += wasm -qtConfig(mirclient): SUBDIRS += mirclient - qtConfig(integrityfb): SUBDIRS += integrity diff --git a/src/plugins/platforms/qnx/qnx.pro b/src/plugins/platforms/qnx/qnx.pro index 96bfa1dd19..bfd56e8d13 100644 --- a/src/plugins/platforms/qnx/qnx.pro +++ b/src/plugins/platforms/qnx/qnx.pro @@ -33,6 +33,7 @@ QT += \ SOURCES = main.cpp \ qqnxbuffer.cpp \ + qqnxforeignwindow.cpp \ qqnxintegration.cpp \ qqnxscreen.cpp \ qqnxwindow.cpp \ @@ -50,6 +51,7 @@ SOURCES = main.cpp \ HEADERS = main.h \ qqnxbuffer.h \ + qqnxforeignwindow.h \ qqnxkeytranslator.h \ qqnxintegration.h \ qqnxscreen.h \ diff --git a/src/plugins/platforms/mirclient/qmirclienttheme.cpp b/src/plugins/platforms/qnx/qqnxforeignwindow.cpp index dcfef7ca67..94608215dc 100644 --- a/src/plugins/platforms/mirclient/qmirclienttheme.cpp +++ b/src/plugins/platforms/qnx/qqnxforeignwindow.cpp @@ -1,6 +1,6 @@ -/**************************************************************************** +/*************************************************************************** ** -** Copyright (C) 2016 Canonical, Ltd. +** Copyright (C) 2018 QNX Software Systems. All rights reserved. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the plugins of the Qt Toolkit. @@ -37,31 +37,29 @@ ** ****************************************************************************/ +#include "qqnxforeignwindow.h" +#include "qqnxintegration.h" -#include "qmirclienttheme.h" +QT_BEGIN_NAMESPACE -#include <QtCore/QVariant> - -const char *QMirClientTheme::name = "ubuntu"; - -QMirClientTheme::QMirClientTheme() +QQnxForeignWindow::QQnxForeignWindow(QWindow *window, + screen_context_t context, + screen_window_t screenWindow) + : QQnxWindow(window, context, screenWindow) { + initWindow(); } -QMirClientTheme::~QMirClientTheme() +bool QQnxForeignWindow::isForeignWindow() const { + return true; } -QVariant QMirClientTheme::themeHint(ThemeHint hint) const +int QQnxForeignWindow::pixelFormat() const { - if (hint == QPlatformTheme::SystemIconThemeName) { - QByteArray iconTheme = qgetenv("QTUBUNTU_ICON_THEME"); - if (iconTheme.isEmpty()) { - return QVariant(QStringLiteral("ubuntu-mobile")); - } else { - return QVariant(QString(iconTheme)); - } - } else { - return QGenericUnixTheme::themeHint(hint); - } + int result = SCREEN_FORMAT_RGBA8888; + screen_get_window_property_iv(nativeHandle(), SCREEN_PROPERTY_FORMAT, &result); + return result; } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/mirclient/qmirclientdebugextension.h b/src/plugins/platforms/qnx/qqnxforeignwindow.h index 0596561d77..22dde643e4 100644 --- a/src/plugins/platforms/mirclient/qmirclientdebugextension.h +++ b/src/plugins/platforms/qnx/qqnxforeignwindow.h @@ -1,6 +1,6 @@ -/**************************************************************************** +/*************************************************************************** ** -** Copyright (C) 2016 Canonical, Ltd. +** Copyright (C) 2018 QNX Software Systems. All rights reserved. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the plugins of the Qt Toolkit. @@ -37,27 +37,25 @@ ** ****************************************************************************/ +#ifndef QQNXFOREIGNWINDOW_H +#define QQNXFOREIGNWINDOW_H -#ifndef QMIRCLIENTDEBUGEXTENSION_H -#define QMIRCLIENTDEBUGEXTENSION_H +#include "qqnxwindow.h" -#include <QPoint> -#include <QLibrary> -struct MirSurface; +QT_BEGIN_NAMESPACE -typedef bool (*MapperPrototype)(MirSurface* surface, int x, int y, int* screenX, int* screenY); - - -class QMirClientDebugExtension +class QQnxForeignWindow : public QQnxWindow { public: - QMirClientDebugExtension(); + QQnxForeignWindow(QWindow *window, + screen_context_t context, + screen_window_t screenWindow); - QPoint mapSurfacePointToScreen(MirSurface *, const QPoint &point); - -private: - QLibrary m_mirclientDebug; - MapperPrototype m_mapper; + bool isForeignWindow() const override; + int pixelFormat() const override; + void resetBuffers() override {} }; -#endif // QMIRCLIENTDEBUGEXTENSION_H +QT_END_NAMESPACE + +#endif // QQNXFOREIGNWINDOW_H diff --git a/src/plugins/platforms/qnx/qqnxintegration.cpp b/src/plugins/platforms/qnx/qqnxintegration.cpp index a45dcabeb7..f479e94988 100644 --- a/src/plugins/platforms/qnx/qqnxintegration.cpp +++ b/src/plugins/platforms/qnx/qqnxintegration.cpp @@ -51,6 +51,7 @@ #include "qqnxabstractvirtualkeyboard.h" #include "qqnxservices.h" +#include "qqnxforeignwindow.h" #include "qqnxrasterwindow.h" #if !defined(QT_NO_OPENGL) #include "qqnxeglwindow.h" @@ -147,6 +148,7 @@ static inline int getContextCapabilities(const QStringList ¶mList) QQnxIntegration::QQnxIntegration(const QStringList ¶mList) : QPlatformIntegration() + , m_screenContextId(256, 0) , m_screenEventThread(0) , m_navigatorEventHandler(new QQnxNavigatorEventHandler()) , m_virtualKeyboard(0) @@ -178,6 +180,11 @@ QQnxIntegration::QQnxIntegration(const QStringList ¶mList) qFatal("%s - Screen: Failed to create screen context - Error: %s (%i)", Q_FUNC_INFO, strerror(errno), errno); } + screen_get_context_property_cv(m_screenContext, + SCREEN_PROPERTY_ID, + m_screenContextId.size(), + m_screenContextId.data()); + m_screenContextId.resize(strlen(m_screenContextId.constData())); #if QT_CONFIG(qqnx_pps) // Create/start navigator event notifier @@ -310,6 +317,7 @@ bool QQnxIntegration::hasCapability(QPlatformIntegration::Capability cap) const qIntegrationDebug(); switch (cap) { case MultipleWindows: + case ForeignWindows: case ThreadedPixmaps: return true; #if !defined(QT_NO_OPENGL) @@ -323,6 +331,18 @@ bool QQnxIntegration::hasCapability(QPlatformIntegration::Capability cap) const } } +QPlatformWindow *QQnxIntegration::createForeignWindow(QWindow *window, WId nativeHandle) const +{ + screen_window_t screenWindow = reinterpret_cast<screen_window_t>(nativeHandle); + if (this->window(screenWindow)) { + qWarning() << "QWindow already created for foreign window" + << screenWindow; + return nullptr; + } + + return new QQnxForeignWindow(window, m_screenContext, screenWindow); +} + QPlatformWindow *QQnxIntegration::createPlatformWindow(QWindow *window) const { qIntegrationDebug(); @@ -478,7 +498,7 @@ QPlatformServices * QQnxIntegration::services() const return m_services; } -QWindow *QQnxIntegration::window(screen_window_t qnxWindow) +QWindow *QQnxIntegration::window(screen_window_t qnxWindow) const { qIntegrationDebug(); QMutexLocker locker(&m_windowMapperMutex); @@ -587,12 +607,11 @@ QList<screen_display_t *> QQnxIntegration::sortDisplays(screen_display_t *availa // Move all displays with matching ID from the intermediate list // to the beginning of the ordered list - QMutableListIterator<screen_display_t *> iter(allDisplays); - while (iter.hasNext()) { - screen_display_t *display = iter.next(); + for (auto it = allDisplays.begin(), end = allDisplays.end(); it != end; ++it) { + screen_display_t *display = *it; if (getIdOfDisplay(*display) == requestedValue) { orderedDisplays.append(display); - iter.remove(); + allDisplays.erase(it); break; } } @@ -706,6 +725,11 @@ screen_context_t QQnxIntegration::screenContext() return m_screenContext; } +QByteArray QQnxIntegration::screenContextId() +{ + return m_screenContextId; +} + QQnxNavigatorEventHandler *QQnxIntegration::navigatorEventHandler() { return m_navigatorEventHandler; diff --git a/src/plugins/platforms/qnx/qqnxintegration.h b/src/plugins/platforms/qnx/qqnxintegration.h index 366556dc4b..0bf37880d1 100644 --- a/src/plugins/platforms/qnx/qqnxintegration.h +++ b/src/plugins/platforms/qnx/qqnxintegration.h @@ -92,6 +92,7 @@ public: bool hasCapability(QPlatformIntegration::Capability cap) const override; + QPlatformWindow *createForeignWindow(QWindow *window, WId nativeHandle) const override; QPlatformWindow *createPlatformWindow(QWindow *window) const override; QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const override; @@ -123,7 +124,7 @@ public: QPlatformServices *services() const override; - QWindow *window(screen_window_t qnxWindow); + QWindow *window(screen_window_t qnxWindow) const; QQnxScreen *screenForNative(screen_display_t qnxScreen) const; @@ -132,6 +133,7 @@ public: QQnxScreen *primaryDisplay() const; Options options() const; screen_context_t screenContext(); + QByteArray screenContextId(); QQnxNavigatorEventHandler *navigatorEventHandler(); @@ -145,6 +147,7 @@ private: int displayCount); screen_context_t m_screenContext; + QByteArray m_screenContextId; QQnxScreenEventThread *m_screenEventThread; QQnxNavigatorEventHandler *m_navigatorEventHandler; QQnxAbstractVirtualKeyboard *m_virtualKeyboard; @@ -168,7 +171,7 @@ private: QSimpleDrag *m_drag; #endif QQnxWindowMapper m_windowMapper; - QMutex m_windowMapperMutex; + mutable QMutex m_windowMapperMutex; Options m_options; diff --git a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp index f29e11489b..a9b5860187 100644 --- a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp +++ b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp @@ -45,6 +45,7 @@ #include "qqnxkeytranslator.h" #include "qqnxscreen.h" #include "qqnxscreeneventfilter.h" +#include "qqnxscreentraits.h" #include <QDebug> #include <QGuiApplication> @@ -89,6 +90,51 @@ static QString capKeyString(int cap, int modifiers, int key) return QString(); } +template <typename T> +static void finishCloseEvent(screen_event_t event) +{ + T t; + screen_get_event_property_pv(event, + screen_traits<T>::propertyName, + reinterpret_cast<void**>(&t)); + screen_traits<T>::destroy(t); +} + +static void finishCloseEvent(screen_event_t event) +{ + // Let libscreen know that we're finished with anything that may have been acquired. + int objectType = SCREEN_OBJECT_TYPE_CONTEXT; + screen_get_event_property_iv(event, SCREEN_PROPERTY_OBJECT_TYPE, &objectType); + switch (objectType) { + case SCREEN_OBJECT_TYPE_CONTEXT: + finishCloseEvent<screen_context_t>(event); + break; + case SCREEN_OBJECT_TYPE_DEVICE: + finishCloseEvent<screen_device_t>(event); + break; + case SCREEN_OBJECT_TYPE_DISPLAY: + // no screen_destroy_display + break; + case SCREEN_OBJECT_TYPE_GROUP: + finishCloseEvent<screen_group_t>(event); + break; + case SCREEN_OBJECT_TYPE_PIXMAP: + finishCloseEvent<screen_pixmap_t>(event); + break; + case SCREEN_OBJECT_TYPE_SESSION: + finishCloseEvent<screen_session_t>(event); + break; +#if _SCREEN_VERSION >= _SCREEN_MAKE_VERSION(2, 0, 0) + case SCREEN_OBJECT_TYPE_STREAM: + finishCloseEvent<screen_stream_t>(event); + break; +#endif + case SCREEN_OBJECT_TYPE_WINDOW: + finishCloseEvent<screen_window_t>(event); + break; + } +} + QT_BEGIN_NAMESPACE QQnxScreenEventHandler::QQnxScreenEventHandler(QQnxIntegration *integration) @@ -242,11 +288,18 @@ void QQnxScreenEventHandler::processEvents() break; ++count; +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + qintptr result = 0; +#else long result = 0; +#endif QAbstractEventDispatcher* dispatcher = QAbstractEventDispatcher::instance(); bool handled = dispatcher && dispatcher->filterNativeEvent(QByteArrayLiteral("screen_event_t"), event, &result); if (!handled) handleEvent(event); + + if (type == SCREEN_EVENT_CLOSE) + finishCloseEvent(event); } m_eventThread->armEventsPending(count); @@ -583,7 +636,7 @@ void QQnxScreenEventHandler::handleDisplayEvent(screen_event_t event) // We never remove the primary display, the qpa plugin doesn't support that and it crashes. // To support it, this would be needed: // - Adjust all qnx qpa code which uses screens - // - Make QWidgetBackingStore not dereference a null paint device + // - Make QWidgetRepaintManager not dereference a null paint device // - Create platform resources ( QQnxWindow ) for all QWindow because they would be deleted // when you delete the screen diff --git a/src/plugins/platforms/qnx/qqnxscreentraits.h b/src/plugins/platforms/qnx/qqnxscreentraits.h new file mode 100644 index 0000000000..ebd74141f2 --- /dev/null +++ b/src/plugins/platforms/qnx/qqnxscreentraits.h @@ -0,0 +1,127 @@ +/*************************************************************************** +** +** Copyright (C) 2018 QNX Software Systems. All rights reserved. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQNXSCREENTRAITS_H +#define QQNXSCREENTRAITS_H + +#include <screen/screen.h> + +QT_BEGIN_NAMESPACE + +template <typename T> +class screen_traits +{ +}; + +template <> +class screen_traits<screen_context_t> +{ +public: + typedef screen_context_t screen_type; + static const int propertyName = SCREEN_PROPERTY_CONTEXT; + static int destroy(screen_context_t context) { return screen_destroy_context(context); } +}; + +template <> +class screen_traits<screen_device_t> +{ +public: + typedef screen_device_t screen_type; + static const int propertyName = SCREEN_PROPERTY_DEVICE; + static int destroy(screen_device_t device) { return screen_destroy_device(device); } +}; + +template <> +class screen_traits<screen_display_t> +{ +public: + typedef screen_display_t screen_type; + static const int propertyName = SCREEN_PROPERTY_DISPLAY; +}; + +template <> +class screen_traits<screen_group_t> +{ +public: + typedef screen_group_t screen_type; + static const int propertyName = SCREEN_PROPERTY_GROUP; + static int destroy(screen_group_t group) { return screen_destroy_group(group); } +}; + +template <> +class screen_traits<screen_pixmap_t> +{ +public: + typedef screen_pixmap_t screen_type; + static const int propertyName = SCREEN_PROPERTY_PIXMAP; + static int destroy(screen_pixmap_t pixmap) { return screen_destroy_pixmap(pixmap); } +}; + +template <> +class screen_traits<screen_session_t> +{ +public: + typedef screen_session_t screen_type; + static const int propertyName = SCREEN_PROPERTY_SESSION; + static int destroy(screen_session_t session) { return screen_destroy_session(session); } +}; + +#if _SCREEN_VERSION >= _SCREEN_MAKE_VERSION(2, 0, 0) +template <> +class screen_traits<screen_stream_t> +{ +public: + typedef screen_stream_t screen_type; + static const int propertyName = SCREEN_PROPERTY_STREAM; + static int destroy(screen_stream_t stream) { return screen_destroy_stream(stream); } +}; +#endif + +template <> +class screen_traits<screen_window_t> +{ +public: + typedef screen_window_t screen_type; + static const int propertyName = SCREEN_PROPERTY_WINDOW; + static int destroy(screen_window_t window) { return screen_destroy_window(window); } +}; + +QT_END_NAMESPACE + +#endif // QQNXSCREENTRAITS_H diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp index 7644e28b44..1d3d609017 100644 --- a/src/plugins/platforms/qnx/qqnxwindow.cpp +++ b/src/plugins/platforms/qnx/qqnxwindow.cpp @@ -155,6 +155,7 @@ QQnxWindow::QQnxWindow(QWindow *window, screen_context_t context, bool needRootW m_parentWindow(0), m_visible(false), m_exposed(true), + m_foreign(false), m_windowState(Qt::WindowNoState), m_mmRendererWindow(0), m_firstActivateHandled(false) @@ -254,6 +255,39 @@ QQnxWindow::QQnxWindow(QWindow *window, screen_context_t context, bool needRootW } } +QQnxWindow::QQnxWindow(QWindow *window, screen_context_t context, screen_window_t screenWindow) + : QPlatformWindow(window) + , m_screenContext(context) + , m_window(screenWindow) + , m_screen(0) + , m_parentWindow(0) + , m_visible(false) + , m_exposed(true) + , m_foreign(true) + , m_windowState(Qt::WindowNoState) + , m_mmRendererWindow(0) + , m_parentGroupName(256, 0) + , m_isTopLevel(false) +{ + qWindowDebug() << "window =" << window << ", size =" << window->size(); + + collectWindowGroup(); + + screen_get_window_property_cv(m_window, + SCREEN_PROPERTY_PARENT, + m_parentGroupName.size(), + m_parentGroupName.data()); + m_parentGroupName.resize(strlen(m_parentGroupName.constData())); + + // If a window group has been provided join it now. If it's an empty string that's OK too, + // it'll cause us not to join a group (the app will presumably join at some future time). + QVariant parentGroup = window->property("qnxInitialWindowGroup"); + if (!parentGroup.isValid()) + parentGroup = window->property("_q_platform_qnxParentGroup"); + if (parentGroup.isValid() && parentGroup.canConvert<QByteArray>()) + joinWindowGroup(parentGroup.toByteArray()); +} + QQnxWindow::~QQnxWindow() { qWindowDebug() << "window =" << window(); @@ -270,7 +304,11 @@ QQnxWindow::~QQnxWindow() m_screen->updateHierarchy(); // Cleanup QNX window and its buffers - screen_destroy_window(m_window); + // Foreign windows are cleaned up externally after the CLOSE event has been handled. + if (m_foreign) + removeContextPermission(); + else + screen_destroy_window(m_window); } void QQnxWindow::setGeometry(const QRect &rect) @@ -793,14 +831,24 @@ void QQnxWindow::initWindow() setGeometryHelper(shouldMakeFullScreen() ? screen()->geometry() : window()->geometry()); } -void QQnxWindow::createWindowGroup() +void QQnxWindow::collectWindowGroup() { - // Generate a random window group name - m_windowGroupName = QUuid::createUuid().toByteArray(); + QByteArray groupName(256, 0); + Q_SCREEN_CHECKERROR(screen_get_window_property_cv(m_window, + SCREEN_PROPERTY_GROUP, + groupName.size(), + groupName.data()), + "Failed to retrieve window group"); + groupName.resize(strlen(groupName.constData())); + m_windowGroupName = groupName; +} - // Create window group so child windows can be parented by container window - Q_SCREEN_CHECKERROR(screen_create_window_group(m_window, m_windowGroupName.constData()), +void QQnxWindow::createWindowGroup() +{ + Q_SCREEN_CHECKERROR(screen_create_window_group(m_window, nullptr), "Failed to create window group"); + + collectWindowGroup(); } void QQnxWindow::joinWindowGroup(const QByteArray &groupName) @@ -809,6 +857,17 @@ void QQnxWindow::joinWindowGroup(const QByteArray &groupName) qWindowDebug() << "group:" << groupName; + // screen has this annoying habit of generating a CLOSE/CREATE when the owner context of + // the parent group moves a foreign window to another group that it also owns. The + // CLOSE/CREATE changes the identity of the foreign window. Usually, this is undesirable. + // To prevent this CLOSE/CREATE when changing the parent group, we temporarily add a + // context permission for the Qt context. screen won't send a CLOSE/CREATE when the + // context has some permission other than the PARENT permission. If there isn't a new + // group (the window has no parent), this context permission is left in place. + + if (m_foreign && !m_parentGroupName.isEmpty())\ + addContextPermission(); + if (!groupName.isEmpty()) { if (groupName != m_parentGroupName) { screen_join_window_group(m_window, groupName); @@ -827,6 +886,9 @@ void QQnxWindow::joinWindowGroup(const QByteArray &groupName) m_parentGroupName = ""; } + if (m_foreign && !groupName.isEmpty()) + removeContextPermission(); + if (changed) screen_flush_context(m_screenContext, 0); } @@ -899,4 +961,26 @@ bool QQnxWindow::focusable() const return (window()->flags() & Qt::WindowDoesNotAcceptFocus) != Qt::WindowDoesNotAcceptFocus; } +void QQnxWindow::addContextPermission() +{ + QByteArray grantString("context:"); + grantString.append(QQnxIntegration::instance()->screenContextId()); + grantString.append(":rw-"); + screen_set_window_property_cv(m_window, + SCREEN_PROPERTY_PERMISSIONS, + grantString.length(), + grantString.data()); +} + +void QQnxWindow::removeContextPermission() +{ + QByteArray revokeString("context:"); + revokeString.append(QQnxIntegration::instance()->screenContextId()); + revokeString.append(":---"); + screen_set_window_property_cv(m_window, + SCREEN_PROPERTY_PERMISSIONS, + revokeString.length(), + revokeString.data()); +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/qnx/qqnxwindow.h b/src/plugins/platforms/qnx/qqnxwindow.h index 20c38cb4b7..9040619c41 100644 --- a/src/plugins/platforms/qnx/qqnxwindow.h +++ b/src/plugins/platforms/qnx/qqnxwindow.h @@ -64,7 +64,8 @@ class QQnxWindow : public QPlatformWindow { friend class QQnxScreen; public: - QQnxWindow(QWindow *window, screen_context_t context, bool needRootWindow); + explicit QQnxWindow(QWindow *window, screen_context_t context, bool needRootWindow); + explicit QQnxWindow(QWindow *window, screen_context_t context, screen_window_t screenWindow); virtual ~QQnxWindow(); void setGeometry(const QRect &rect) override; @@ -124,6 +125,7 @@ protected: screen_context_t m_screenContext; private: + void collectWindowGroup(); void createWindowGroup(); void setGeometryHelper(const QRect &rect); void removeFromParent(); @@ -135,6 +137,9 @@ private: bool showWithoutActivating() const; bool focusable() const; + void addContextPermission(); + void removeContextPermission(); + screen_window_t m_window; QSize m_bufferSize; @@ -144,6 +149,7 @@ private: QScopedPointer<QQnxAbstractCover> m_cover; bool m_visible; bool m_exposed; + bool m_foreign; QRect m_unmaximizedGeometry; Qt::WindowStates m_windowState; QString m_mmRendererWindowName; diff --git a/src/plugins/platforms/vnc/qvnc_p.h b/src/plugins/platforms/vnc/qvnc_p.h index 338fae9f87..f7f2f74ddb 100644 --- a/src/plugins/platforms/vnc/qvnc_p.h +++ b/src/plugins/platforms/vnc/qvnc_p.h @@ -139,7 +139,7 @@ public: class QRfbServerInit { public: - QRfbServerInit() { name = 0; } + QRfbServerInit() { name = nullptr; } ~QRfbServerInit() { delete[] name; } int size() const { return QRfbPixelFormat::size() + 8 + strlen(name); } diff --git a/src/plugins/platforms/vnc/qvncclient.cpp b/src/plugins/platforms/vnc/qvncclient.cpp index 9dfe873927..3a373a5e4b 100644 --- a/src/plugins/platforms/vnc/qvncclient.cpp +++ b/src/plugins/platforms/vnc/qvncclient.cpp @@ -587,9 +587,18 @@ void QVncClient::frameBufferUpdateRequest() void QVncClient::pointerEvent() { QRfbPointerEvent ev; + static int buttonState = Qt::NoButton; if (ev.read(m_clientSocket)) { - const QPoint pos = m_server->screen()->geometry().topLeft() + QPoint(ev.x, ev.y); - QWindowSystemInterface::handleMouseEvent(0, pos, pos, ev.buttons, QGuiApplication::keyboardModifiers()); + const QPointF pos = m_server->screen()->geometry().topLeft() + QPoint(ev.x, ev.y); + int buttonStateChange = buttonState ^ int(ev.buttons); + QEvent::Type type = QEvent::MouseMove; + if (int(ev.buttons) > buttonState) + type = QEvent::MouseButtonPress; + else if (int(ev.buttons) < buttonState) + type = QEvent::MouseButtonRelease; + QWindowSystemInterface::handleMouseEvent(nullptr, pos, pos, ev.buttons, Qt::MouseButton(buttonStateChange), + type, QGuiApplication::keyboardModifiers()); + buttonState = int(ev.buttons); m_handleMsg = false; } } diff --git a/src/plugins/platforms/vnc/qvncscreen.h b/src/plugins/platforms/vnc/qvncscreen.h index e69aa90d41..db658d4ecc 100644 --- a/src/plugins/platforms/vnc/qvncscreen.h +++ b/src/plugins/platforms/vnc/qvncscreen.h @@ -82,12 +82,12 @@ public: qreal dpiX = 96; qreal dpiY = 96; - QVncDirtyMap *dirty = 0; + QVncDirtyMap *dirty = nullptr; QRegion dirtyRegion; int refreshRate = 30; - QVncServer *vncServer = 0; + QVncServer *vncServer = nullptr; #if QT_CONFIG(cursor) - QVncClientCursor *clientCursor = 0; + QVncClientCursor *clientCursor = nullptr; #endif }; diff --git a/src/plugins/platforms/wasm/qtlogo.svg b/src/plugins/platforms/wasm/qtlogo.svg index cb8989bb79..ad7c7776bf 100644 --- a/src/plugins/platforms/wasm/qtlogo.svg +++ b/src/plugins/platforms/wasm/qtlogo.svg @@ -5,15 +5,10 @@ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="462pt" height="339pt" viewBox="0 0 462 339" - version="1.1" - id="svg2" - inkscape:version="0.91 r13725" - sodipodi:docname="TheQtCompany_logo_2.svg"> + version="1.1"> <metadata id="metadata20"> <rdf:RDF> @@ -26,28 +21,6 @@ </cc:Work> </rdf:RDF> </metadata> - <defs - id="defs18" /> - <sodipodi:namedview - pagecolor="#ffffff" - bordercolor="#666666" - borderopacity="1" - objecttolerance="10" - gridtolerance="10" - guidetolerance="10" - inkscape:pageopacity="0" - inkscape:pageshadow="2" - inkscape:window-width="1536" - inkscape:window-height="801" - id="namedview16" - showgrid="false" - inkscape:zoom="1.1138643" - inkscape:cx="270.58047" - inkscape:cy="174.65092" - inkscape:window-x="-8" - inkscape:window-y="-8" - inkscape:window-maximized="1" - inkscape:current-layer="svg2" /> <path fill="#41cd52" d=" M 63.50 0.00 L 462.00 0.00 L 462.00 274.79 C 440.60 296.26 419.13 317.66 397.61 339.00 L 0.00 339.00 L 0.00 63.39 C 21.08 42.18 42.34 21.13 63.50 0.00 Z" diff --git a/src/plugins/platforms/wasm/qwasmbackingstore.cpp b/src/plugins/platforms/wasm/qwasmbackingstore.cpp index e8eda2605f..7e8a382512 100644 --- a/src/plugins/platforms/wasm/qwasmbackingstore.cpp +++ b/src/plugins/platforms/wasm/qwasmbackingstore.cpp @@ -81,6 +81,11 @@ void QWasmBackingStore::updateTexture() if (m_dirty.isNull()) return; + if (m_recreateTexture && m_texture->isCreated()) { + m_recreateTexture = false; + m_texture->destroy(); + } + if (!m_texture->isCreated()) { m_texture->setMinificationFilter(QOpenGLTexture::Nearest); m_texture->setMagnificationFilter(QOpenGLTexture::Nearest); @@ -146,9 +151,7 @@ void QWasmBackingStore::resize(const QSize &size, const QRegion &staticContents) m_image = QImage(size * window()->devicePixelRatio(), QImage::Format_RGB32); m_image.setDevicePixelRatio(window()->devicePixelRatio()); - - if (m_texture->isCreated()) - m_texture->destroy(); + m_recreateTexture = true; } QImage QWasmBackingStore::toImage() const diff --git a/src/plugins/platforms/wasm/qwasmbackingstore.h b/src/plugins/platforms/wasm/qwasmbackingstore.h index 4bca83c457..b93c96b483 100644 --- a/src/plugins/platforms/wasm/qwasmbackingstore.h +++ b/src/plugins/platforms/wasm/qwasmbackingstore.h @@ -64,6 +64,7 @@ private: QImage m_image; QScopedPointer<QOpenGLTexture> m_texture; QRegion m_dirty; + bool m_recreateTexture = false; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/wasm/qwasmcompositor.cpp b/src/plugins/platforms/wasm/qwasmcompositor.cpp index 6d211667be..a810880c43 100644 --- a/src/plugins/platforms/wasm/qwasmcompositor.cpp +++ b/src/plugins/platforms/wasm/qwasmcompositor.cpp @@ -681,7 +681,7 @@ void QWasmCompositor::frame() QWasmWindow *someWindow = nullptr; - foreach (QWasmWindow *window, m_windowStack) { + for (QWasmWindow *window : qAsConst(m_windowStack)) { if (window->window()->surfaceClass() == QSurface::Window && qt_window_private(static_cast<QWindow *>(window->window()))->receivedExpose) { someWindow = window; @@ -715,7 +715,7 @@ void QWasmCompositor::frame() m_blitter->bind(); m_blitter->setRedBlueSwizzle(true); - foreach (QWasmWindow *window, m_windowStack) { + for (QWasmWindow *window : qAsConst(m_windowStack)) { QWasmCompositedWindow &compositedWindow = m_compositedWindows[window]; if (!compositedWindow.visible) diff --git a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp index 43e82435cf..ad94ba9c77 100644 --- a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp +++ b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp @@ -780,6 +780,60 @@ quint64 QWasmEventTranslator::getTimestamp() return QDeadlineTimer::current().deadlineNSecs() / 1000; } +struct KeyMapping { Qt::Key from, to; }; + +constexpr KeyMapping tildeKeyTable[] = { // ~ + { Qt::Key_A, Qt::Key_Atilde }, + { Qt::Key_N, Qt::Key_Ntilde }, + { Qt::Key_O, Qt::Key_Otilde }, +}; +constexpr KeyMapping graveKeyTable[] = { // ` + { Qt::Key_A, Qt::Key_Agrave }, + { Qt::Key_E, Qt::Key_Egrave }, + { Qt::Key_I, Qt::Key_Igrave }, + { Qt::Key_O, Qt::Key_Ograve }, + { Qt::Key_U, Qt::Key_Ugrave }, +}; +constexpr KeyMapping acuteKeyTable[] = { // ' + { Qt::Key_A, Qt::Key_Aacute }, + { Qt::Key_E, Qt::Key_Eacute }, + { Qt::Key_I, Qt::Key_Iacute }, + { Qt::Key_O, Qt::Key_Oacute }, + { Qt::Key_U, Qt::Key_Uacute }, + { Qt::Key_Y, Qt::Key_Yacute }, +}; +constexpr KeyMapping diaeresisKeyTable[] = { // umlaut ¨ + { Qt::Key_A, Qt::Key_Adiaeresis }, + { Qt::Key_E, Qt::Key_Ediaeresis }, + { Qt::Key_I, Qt::Key_Idiaeresis }, + { Qt::Key_O, Qt::Key_Odiaeresis }, + { Qt::Key_U, Qt::Key_Udiaeresis }, + { Qt::Key_Y, Qt::Key_ydiaeresis }, +}; +constexpr KeyMapping circumflexKeyTable[] = { // ^ + { Qt::Key_A, Qt::Key_Acircumflex }, + { Qt::Key_E, Qt::Key_Ecircumflex }, + { Qt::Key_I, Qt::Key_Icircumflex }, + { Qt::Key_O, Qt::Key_Ocircumflex }, + { Qt::Key_U, Qt::Key_Ucircumflex }, +}; + +static Qt::Key find_impl(const KeyMapping *first, const KeyMapping *last, Qt::Key key) noexcept +{ + while (first != last) { + if (first->from == key) + return first->to; + ++first; + } + return Qt::Key_unknown; +} + +template <size_t N> +static Qt::Key find(const KeyMapping (&map)[N], Qt::Key key) noexcept +{ + return find_impl(map, map + N, key); +} + Qt::Key QWasmEventTranslator::translateDeadKey(Qt::Key deadKey, Qt::Key accentBaseKey) { Qt::Key wasmKey = Qt::Key_unknown; @@ -789,25 +843,25 @@ Qt::Key QWasmEventTranslator::translateDeadKey(Qt::Key deadKey, Qt::Key accentBa #else case Qt::Key_O: // ´ Key_Dead_Grave #endif - wasmKey = graveKeyTable.value(accentBaseKey); + wasmKey = find(graveKeyTable, accentBaseKey); break; case Qt::Key_E: // ´ Key_Dead_Acute - wasmKey = acuteKeyTable.value(accentBaseKey); + wasmKey = find(acuteKeyTable, accentBaseKey); break; case Qt::Key_AsciiTilde: case Qt::Key_N:// Key_Dead_Tilde - wasmKey = tildeKeyTable.value(accentBaseKey); + wasmKey = find(tildeKeyTable, accentBaseKey); break; #ifndef Q_OS_MACOS case Qt::Key_QuoteLeft: #endif case Qt::Key_U:// ¨ Key_Dead_Diaeresis - wasmKey = diaeresisKeyTable.value(accentBaseKey); + wasmKey = find(diaeresisKeyTable, accentBaseKey); break; case Qt::Key_I:// macOS Key_Dead_Circumflex case Qt::Key_6:// linux case Qt::Key_Apostrophe:// linux - wasmKey = circumflexKeyTable.value(accentBaseKey); + wasmKey = find(circumflexKeyTable, accentBaseKey); break; default: break; diff --git a/src/plugins/platforms/wasm/qwasmeventtranslator.h b/src/plugins/platforms/wasm/qwasmeventtranslator.h index 1655b7226a..568ae00732 100644 --- a/src/plugins/platforms/wasm/qwasmeventtranslator.h +++ b/src/plugins/platforms/wasm/qwasmeventtranslator.h @@ -77,42 +77,6 @@ private: Qt::Key translateDeadKey(Qt::Key deadKey, Qt::Key accentBaseKey); - QHash<Qt::Key , Qt::Key> tildeKeyTable { // ~ - { Qt::Key_A, Qt::Key_Atilde}, - { Qt::Key_N, Qt::Key_Ntilde}, - { Qt::Key_O, Qt::Key_Otilde} - }; - QHash<Qt::Key , Qt::Key> graveKeyTable { // ` - { Qt::Key_A, Qt::Key_Agrave}, - { Qt::Key_E, Qt::Key_Egrave}, - { Qt::Key_I, Qt::Key_Igrave}, - { Qt::Key_O, Qt::Key_Ograve}, - { Qt::Key_U, Qt::Key_Ugrave} - }; - QHash<Qt::Key , Qt::Key> acuteKeyTable { // ' - { Qt::Key_A, Qt::Key_Aacute}, - { Qt::Key_E, Qt::Key_Eacute}, - { Qt::Key_I, Qt::Key_Iacute}, - { Qt::Key_O, Qt::Key_Oacute}, - { Qt::Key_U, Qt::Key_Uacute}, - { Qt::Key_Y, Qt::Key_Yacute} - }; - QHash<Qt::Key , Qt::Key> diaeresisKeyTable { // umlaut ¨ - { Qt::Key_A, Qt::Key_Adiaeresis}, - { Qt::Key_E, Qt::Key_Ediaeresis}, - { Qt::Key_I, Qt::Key_Idiaeresis}, - { Qt::Key_O, Qt::Key_Odiaeresis}, - { Qt::Key_U, Qt::Key_Udiaeresis}, - { Qt::Key_Y, Qt::Key_ydiaeresis} - }; - QHash<Qt::Key , Qt::Key> circumflexKeyTable { // ^ - { Qt::Key_A, Qt::Key_Acircumflex}, - { Qt::Key_E, Qt::Key_Ecircumflex}, - { Qt::Key_I, Qt::Key_Icircumflex}, - { Qt::Key_O, Qt::Key_Ocircumflex}, - { Qt::Key_U, Qt::Key_Ucircumflex} - }; - QMap <int, QPointF> pressedTouchIds; private: diff --git a/src/plugins/platforms/wasm/qwasmfontdatabase.cpp b/src/plugins/platforms/wasm/qwasmfontdatabase.cpp index dc6bb5847e..53e875ead6 100644 --- a/src/plugins/platforms/wasm/qwasmfontdatabase.cpp +++ b/src/plugins/platforms/wasm/qwasmfontdatabase.cpp @@ -38,10 +38,13 @@ void QWasmFontDatabase::populateFontDatabase() // Load font file from resources. Currently // all fonts needs to be bundled with the nexe // as Qt resources. - QStringList fontFileNames = QStringList() << QStringLiteral(":/fonts/DejaVuSansMono.ttf") - << QStringLiteral(":/fonts/Vera.ttf") - << QStringLiteral(":/fonts/DejaVuSans.ttf"); - foreach (const QString &fontFileName, fontFileNames) { + + const QString fontFileNames[] = { + QStringLiteral(":/fonts/DejaVuSansMono.ttf"), + QStringLiteral(":/fonts/Vera.ttf"), + QStringLiteral(":/fonts/DejaVuSans.ttf"), + }; + for (const QString &fontFileName : fontFileNames) { QFile theFont(fontFileName); if (!theFont.open(QIODevice::ReadOnly)) break; diff --git a/src/plugins/platforms/wasm/wasm.pro b/src/plugins/platforms/wasm/wasm.pro index c28df8f893..f8c8175525 100644 --- a/src/plugins/platforms/wasm/wasm.pro +++ b/src/plugins/platforms/wasm/wasm.pro @@ -7,6 +7,8 @@ QT += \ # Avoid X11 header collision, use generic EGL native types DEFINES += QT_EGL_NO_X11 +DEFINES += QT_NO_FOREACH + SOURCES = \ main.cpp \ qwasmintegration.cpp \ diff --git a/src/plugins/platforms/windows/qwin10helpers.cpp b/src/plugins/platforms/windows/qwin10helpers.cpp index cc17d8798f..9a7fce9cd5 100644 --- a/src/plugins/platforms/windows/qwin10helpers.cpp +++ b/src/plugins/platforms/windows/qwin10helpers.cpp @@ -137,7 +137,7 @@ bool qt_windowsIsTabletMode(HWND hwnd) const wchar_t uiViewSettingsId[] = L"Windows.UI.ViewManagement.UIViewSettings"; HSTRING_HEADER uiViewSettingsIdRefHeader; HSTRING uiViewSettingsIdHs = nullptr; - const UINT32 uiViewSettingsIdLen = UINT32(sizeof(uiViewSettingsId) / sizeof(uiViewSettingsId[0]) - 1); + const auto uiViewSettingsIdLen = UINT32(sizeof(uiViewSettingsId) / sizeof(uiViewSettingsId[0]) - 1); if (FAILED(baseComDll.windowsCreateStringReference(uiViewSettingsId, uiViewSettingsIdLen, &uiViewSettingsIdRefHeader, &uiViewSettingsIdHs))) return false; diff --git a/src/plugins/platforms/windows/qwindowsbackingstore.cpp b/src/plugins/platforms/windows/qwindowsbackingstore.cpp index 68807fabdd..bd7bdc55d1 100644 --- a/src/plugins/platforms/windows/qwindowsbackingstore.cpp +++ b/src/plugins/platforms/windows/qwindowsbackingstore.cpp @@ -158,7 +158,7 @@ void QWindowsBackingStore::resize(const QSize &size, const QRegion ®ion) format = qt_maybeAlphaVersionWithSameDepth(format); QWindowsNativeImage *oldwni = m_image.data(); - QWindowsNativeImage *newwni = new QWindowsNativeImage(size.width(), size.height(), format); + auto *newwni = new QWindowsNativeImage(size.width(), size.height(), format); if (oldwni && !region.isEmpty()) { const QImage &oldimg(oldwni->image()); diff --git a/src/plugins/platforms/windows/qwindowsbackingstore.h b/src/plugins/platforms/windows/qwindowsbackingstore.h index 088ab3b257..b96c8f0e61 100644 --- a/src/plugins/platforms/windows/qwindowsbackingstore.h +++ b/src/plugins/platforms/windows/qwindowsbackingstore.h @@ -52,7 +52,7 @@ class QWindowsNativeImage; class QWindowsBackingStore : public QPlatformBackingStore { - Q_DISABLE_COPY(QWindowsBackingStore) + Q_DISABLE_COPY_MOVE(QWindowsBackingStore) public: QWindowsBackingStore(QWindow *window); ~QWindowsBackingStore() override; diff --git a/src/plugins/platforms/windows/qwindowsclipboard.cpp b/src/plugins/platforms/windows/qwindowsclipboard.cpp index b87e43f3f7..4e6d3306e1 100644 --- a/src/plugins/platforms/windows/qwindowsclipboard.cpp +++ b/src/plugins/platforms/windows/qwindowsclipboard.cpp @@ -115,12 +115,21 @@ static QDebug operator<<(QDebug d, const QMimeData *mimeData) IDataObject *QWindowsClipboardRetrievalMimeData::retrieveDataObject() const { + enum : int { attempts = 3 }; IDataObject * pDataObj = nullptr; - if (OleGetClipboard(&pDataObj) == S_OK) { - if (QWindowsContext::verbose > 1) - qCDebug(lcQpaMime) << __FUNCTION__ << pDataObj; - return pDataObj; + // QTBUG-53979, retry in case the other application has clipboard locked + for (int i = 1; i <= attempts; ++i) { + if (SUCCEEDED(OleGetClipboard(&pDataObj))) { + if (QWindowsContext::verbose > 1) + qCDebug(lcQpaMime) << __FUNCTION__ << pDataObj; + return pDataObj; + } + qCWarning(lcQpaMime, i == attempts + ? "Unable to obtain clipboard." + : "Retrying to obtain clipboard."); + QThread::msleep(50); } + return nullptr; } diff --git a/src/plugins/platforms/windows/qwindowsclipboard.h b/src/plugins/platforms/windows/qwindowsclipboard.h index 469d638b89..24a6bc908d 100644 --- a/src/plugins/platforms/windows/qwindowsclipboard.h +++ b/src/plugins/platforms/windows/qwindowsclipboard.h @@ -58,7 +58,7 @@ protected: class QWindowsClipboard : public QPlatformClipboard { - Q_DISABLE_COPY(QWindowsClipboard) + Q_DISABLE_COPY_MOVE(QWindowsClipboard) public: QWindowsClipboard(); ~QWindowsClipboard() override; @@ -87,8 +87,8 @@ private: QWindowsClipboardRetrievalMimeData m_retrievalData; QWindowsOleDataObject *m_data = nullptr; - HWND m_clipboardViewer = 0; - HWND m_nextClipboardViewer = 0; + HWND m_clipboardViewer = nullptr; + HWND m_nextClipboardViewer = nullptr; bool m_formatListenerRegistered = false; }; diff --git a/src/plugins/platforms/windows/qwindowscombase.h b/src/plugins/platforms/windows/qwindowscombase.h index 6b25d665dc..45cba9c68b 100644 --- a/src/plugins/platforms/windows/qwindowscombase.h +++ b/src/plugins/platforms/windows/qwindowscombase.h @@ -80,7 +80,7 @@ bool qWindowsComQueryUnknownInterfaceMulti(Derived *d, REFIID id, LPVOID *iface) // Helper base class to provide IUnknown methods for COM classes (single inheritance) template <class ComInterface> class QWindowsComBase : public ComInterface { - Q_DISABLE_COPY(QWindowsComBase) + Q_DISABLE_COPY_MOVE(QWindowsComBase) public: explicit QWindowsComBase(ULONG initialRefCount = 1) : m_ref(initialRefCount) {} virtual ~QWindowsComBase() = default; diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index 38b9823d6b..f7d04b667d 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -79,6 +79,7 @@ #include <QtCore/qscopedpointer.h> #include <QtCore/quuid.h> #include <QtCore/private/qsystemlibrary_p.h> +#include <QtCore/private/qwinregistry_p.h> #include <QtEventDispatcherSupport/private/qwindowsguieventdispatcher_p.h> @@ -134,8 +135,8 @@ static inline bool useRTL_Extensions() #if QT_CONFIG(sessionmanager) static inline QWindowsSessionManager *platformSessionManager() { - QGuiApplicationPrivate *guiPrivate = static_cast<QGuiApplicationPrivate*>(QObjectPrivate::get(qApp)); - QSessionManagerPrivate *managerPrivate = static_cast<QSessionManagerPrivate*>(QObjectPrivate::get(guiPrivate->session_manager)); + auto *guiPrivate = static_cast<QGuiApplicationPrivate*>(QObjectPrivate::get(qApp)); + auto *managerPrivate = static_cast<QSessionManagerPrivate*>(QObjectPrivate::get(guiPrivate->session_manager)); return static_cast<QWindowsSessionManager *>(managerPrivate->platformSessionManager); } @@ -548,7 +549,7 @@ QString QWindowsContext::registerWindowClass(QString cname, // add a UUID. static int classExists = -1; - const HINSTANCE appInstance = static_cast<HINSTANCE>(GetModuleHandle(nullptr)); + const auto appInstance = static_cast<HINSTANCE>(GetModuleHandle(nullptr)); if (classExists == -1) { WNDCLASS wcinfo; classExists = GetClassInfo(appInstance, reinterpret_cast<LPCWSTR>(cname.utf16()), &wcinfo); @@ -594,14 +595,14 @@ QString QWindowsContext::registerWindowClass(QString cname, d->m_registeredWindowClassNames.insert(cname); qCDebug(lcQpaWindows).nospace() << __FUNCTION__ << ' ' << cname - << " style=0x" << hex << style << dec + << " style=0x" << Qt::hex << style << Qt::dec << " brush=" << brush << " icon=" << icon << " atom=" << atom; return cname; } void QWindowsContext::unregisterWindowClasses() { - const HINSTANCE appInstance = static_cast<HINSTANCE>(GetModuleHandle(nullptr)); + const auto appInstance = static_cast<HINSTANCE>(GetModuleHandle(nullptr)); for (const QString &name : qAsConst(d->m_registeredWindowClassNames)) { if (!UnregisterClass(reinterpret_cast<LPCWSTR>(name.utf16()), appInstance) && QWindowsContext::verbose) @@ -716,7 +717,7 @@ static inline bool findPlatformWindowHelper(const POINT &screenPoint, unsigned c HWND *hwnd, QWindowsWindow **result) { POINT point = screenPoint; - ScreenToClient(*hwnd, &point); + screenToClient(*hwnd, &point); // Returns parent if inside & none matched. const HWND child = ChildWindowFromPointEx(*hwnd, point, cwexFlags); if (!child || child == *hwnd) @@ -1053,7 +1054,7 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, // For non-client-area messages, these are screen coordinates (as expected // in the MSG structure), otherwise they are client coordinates. if (!(et & QtWindows::NonClientEventFlag)) { - ClientToScreen(msg.hwnd, &msg.pt); + clientToScreen(msg.hwnd, &msg.pt); } } else { GetCursorPos(&msg.pt); @@ -1144,13 +1145,11 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, case QtWindows::QuerySizeHints: d->m_creationContext->applyToMinMaxInfo(reinterpret_cast<MINMAXINFO *>(lParam)); return true; - case QtWindows::ResizeEvent: { - const QSize size(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) - d->m_creationContext->menuHeight); - d->m_creationContext->obtainedGeometry.setSize(size); - } + case QtWindows::ResizeEvent: + d->m_creationContext->obtainedSize = QSize(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); return true; case QtWindows::MoveEvent: - d->m_creationContext->obtainedGeometry.moveTo(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); + d->m_creationContext->obtainedPos = QPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); return true; case QtWindows::NonClientCreate: if (shouldHaveNonClientDpiScaling(d->m_creationContext->window)) @@ -1363,7 +1362,7 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, sessionManager->blocksInteraction(); sessionManager->clearCancellation(); - QGuiApplicationPrivate *qGuiAppPriv = static_cast<QGuiApplicationPrivate*>(QObjectPrivate::get(qApp)); + auto *qGuiAppPriv = static_cast<QGuiApplicationPrivate*>(QObjectPrivate::get(qApp)); qGuiAppPriv->commitData(); if (lParam & ENDSESSION_LOGOFF) @@ -1381,7 +1380,7 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, // we receive the message for each toplevel window included internal hidden ones, // but the aboutToQuit signal should be emitted only once. - QGuiApplicationPrivate *qGuiAppPriv = static_cast<QGuiApplicationPrivate*>(QObjectPrivate::get(qApp)); + auto *qGuiAppPriv = static_cast<QGuiApplicationPrivate*>(QObjectPrivate::get(qApp)); if (endsession && !qGuiAppPriv->aboutToQuitEmitted) { qGuiAppPriv->aboutToQuitEmitted = true; int index = QGuiApplication::staticMetaObject.indexOfSignal("aboutToQuit()"); @@ -1520,28 +1519,13 @@ QTouchDevice *QWindowsContext::touchDevice() const d->m_pointerHandler.touchDevice() : d->m_mouseHandler.touchDevice(); } -static DWORD readDwordRegistrySetting(const wchar_t *regKey, const wchar_t *subKey, DWORD defaultValue) -{ - DWORD result = defaultValue; - HKEY handle; - if (RegOpenKeyEx(HKEY_CURRENT_USER, regKey, 0, KEY_READ, &handle) == ERROR_SUCCESS) { - DWORD type; - if (RegQueryValueEx(handle, subKey, nullptr, &type, nullptr, nullptr) == ERROR_SUCCESS - && type == REG_DWORD) { - DWORD value; - DWORD size = sizeof(result); - if (RegQueryValueEx(handle, subKey, nullptr, nullptr, reinterpret_cast<unsigned char *>(&value), &size) == ERROR_SUCCESS) - result = value; - } - RegCloseKey(handle); - } - return result; -} - DWORD QWindowsContext::readAdvancedExplorerSettings(const wchar_t *subKey, DWORD defaultValue) { - return readDwordRegistrySetting(L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced", - subKey, defaultValue); + const auto value = + QWinRegistryKey(HKEY_CURRENT_USER, + LR"(Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced)") + .dwordValue(subKey); + return value.second ? value.first : defaultValue; } static inline bool isEmptyRect(const RECT &rect) @@ -1594,7 +1578,7 @@ extern "C" LRESULT QT_WIN_CALLBACK qWindowsWndProc(HWND hwnd, UINT message, WPAR if (QWindowsContext::verbose > 1 && lcQpaEvents().isDebugEnabled()) { if (const char *eventName = QWindowsGuiEventDispatcher::windowsMessageName(message)) { qCDebug(lcQpaEvents).nospace() << "EVENT: hwd=" << hwnd << ' ' << eventName - << " msg=0x" << hex << message << " et=0x" << et << dec << " wp=" + << " msg=0x" << Qt::hex << message << " et=0x" << et << Qt::dec << " wp=" << int(wParam) << " at " << GET_X_LPARAM(lParam) << ',' << GET_Y_LPARAM(lParam) << " handled=" << handled; } @@ -1630,7 +1614,11 @@ static inline QByteArray nativeEventType() { return QByteArrayLiteral("windows_g bool QWindowsContext::filterNativeEvent(MSG *msg, LRESULT *result) { QAbstractEventDispatcher *dispatcher = QAbstractEventDispatcher::instance(); +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + qintptr filterResult = 0; +#else long filterResult = 0; +#endif if (dispatcher && dispatcher->filterNativeEvent(nativeEventType(), msg, &filterResult)) { *result = LRESULT(filterResult); return true; @@ -1641,7 +1629,11 @@ bool QWindowsContext::filterNativeEvent(MSG *msg, LRESULT *result) // Send to QWindowSystemInterface bool QWindowsContext::filterNativeEvent(QWindow *window, MSG *msg, LRESULT *result) { +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + qintptr filterResult = 0; +#else long filterResult = 0; +#endif if (QWindowSystemInterface::handleNativeEvent(window, nativeEventType(), msg, &filterResult)) { *result = LRESULT(filterResult); return true; diff --git a/src/plugins/platforms/windows/qwindowscontext.h b/src/plugins/platforms/windows/qwindowscontext.h index 4908f14629..d94ae3f73b 100644 --- a/src/plugins/platforms/windows/qwindowscontext.h +++ b/src/plugins/platforms/windows/qwindowscontext.h @@ -155,7 +155,7 @@ struct QWindowsShcoreDLL { class QWindowsContext { - Q_DISABLE_COPY(QWindowsContext) + Q_DISABLE_COPY_MOVE(QWindowsContext) public: enum SystemInfoFlags @@ -180,11 +180,11 @@ public: QString registerWindowClass(const QWindow *w); QString registerWindowClass(QString cname, WNDPROC proc, - unsigned style = 0, HBRUSH brush = 0, + unsigned style = 0, HBRUSH brush = nullptr, bool icon = false); HWND createDummyWindow(const QString &classNameIn, const wchar_t *windowName, - WNDPROC wndProc = 0, DWORD style = WS_OVERLAPPED); + WNDPROC wndProc = nullptr, DWORD style = WS_OVERLAPPED); HDC displayContext() const; int screenDepth() const; diff --git a/src/plugins/platforms/windows/qwindowscursor.cpp b/src/plugins/platforms/windows/qwindowscursor.cpp index 20a8117304..17e8cffb76 100644 --- a/src/plugins/platforms/windows/qwindowscursor.cpp +++ b/src/plugins/platforms/windows/qwindowscursor.cpp @@ -752,7 +752,7 @@ QPixmap QWindowsCursor::dragDefaultCursor(Qt::DropAction action) const && GetObject(iconInfo.hbmColor, sizeof(BITMAP), &bmColor) && bmColor.bmWidth == bmColor.bmWidthBytes / 4) { const int colorBitsLength = bmColor.bmHeight * bmColor.bmWidthBytes; - uchar *colorBits = new uchar[colorBitsLength]; + auto *colorBits = new uchar[colorBitsLength]; GetBitmapBits(iconInfo.hbmColor, colorBitsLength, colorBits); const QImage colorImage(colorBits, bmColor.bmWidth, bmColor.bmHeight, bmColor.bmWidthBytes, QImage::Format_ARGB32); diff --git a/src/plugins/platforms/windows/qwindowscursor.h b/src/plugins/platforms/windows/qwindowscursor.h index 8495b51a5a..b896f4c7a9 100644 --- a/src/plugins/platforms/windows/qwindowscursor.h +++ b/src/plugins/platforms/windows/qwindowscursor.h @@ -61,14 +61,14 @@ inline bool operator==(const QWindowsPixmapCursorCacheKey &k1, const QWindowsPix return k1.bitmapCacheKey == k2.bitmapCacheKey && k1.maskCacheKey == k2.maskCacheKey; } -inline uint qHash(const QWindowsPixmapCursorCacheKey &k, uint seed) Q_DECL_NOTHROW +inline uint qHash(const QWindowsPixmapCursorCacheKey &k, uint seed) noexcept { return (uint(k.bitmapCacheKey) + uint(k.maskCacheKey)) ^ seed; } class CursorHandle { - Q_DISABLE_COPY(CursorHandle) + Q_DISABLE_COPY_MOVE(CursorHandle) public: explicit CursorHandle(HCURSOR hcursor = nullptr) : m_hcursor(hcursor) {} ~CursorHandle() @@ -84,7 +84,7 @@ private: const HCURSOR m_hcursor; }; -typedef QSharedPointer<CursorHandle> CursorHandlePtr; +using CursorHandlePtr = QSharedPointer<CursorHandle>; class QWindowsCursor : public QPlatformCursor { diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp index 9de3268fc8..b7ab952a1d 100644 --- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp +++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp @@ -271,7 +271,7 @@ QWindowsNativeDialogBase *QWindowsDialogHelperBase<BaseClass>::ensureNativeDialo class QWindowsDialogThread : public QThread { public: - typedef QSharedPointer<QWindowsNativeDialogBase> QWindowsNativeDialogBasePtr; + using QWindowsNativeDialogBasePtr = QSharedPointer<QWindowsNativeDialogBase>; explicit QWindowsDialogThread(const QWindowsNativeDialogBasePtr &d, HWND owner) : m_dialog(d), m_owner(owner) {} @@ -356,7 +356,7 @@ struct FindDialogContext static BOOL QT_WIN_CALLBACK findDialogEnumWindowsProc(HWND hwnd, LPARAM lParam) { - FindDialogContext *context = reinterpret_cast<FindDialogContext *>(lParam); + auto *context = reinterpret_cast<FindDialogContext *>(lParam); DWORD winPid = 0; GetWindowThreadProcessId(hwnd, &winPid); if (winPid != context->processId) @@ -507,7 +507,7 @@ class QWindowsNativeFileDialogBase; class QWindowsNativeFileDialogEventHandler : public QWindowsComBase<IFileDialogEvents> { - Q_DISABLE_COPY(QWindowsNativeFileDialogEventHandler) + Q_DISABLE_COPY_MOVE(QWindowsNativeFileDialogEventHandler) public: static IFileDialogEvents *create(QWindowsNativeFileDialogBase *nativeFileDialog); @@ -531,7 +531,7 @@ private: IFileDialogEvents *QWindowsNativeFileDialogEventHandler::create(QWindowsNativeFileDialogBase *nativeFileDialog) { IFileDialogEvents *result; - QWindowsNativeFileDialogEventHandler *eventHandler = new QWindowsNativeFileDialogEventHandler(nativeFileDialog); + auto *eventHandler = new QWindowsNativeFileDialogEventHandler(nativeFileDialog); if (FAILED(eventHandler->QueryInterface(IID_IFileDialogEvents, reinterpret_cast<void **>(&result)))) { qErrnoWarning("Unable to obtain IFileDialogEvents"); return nullptr; @@ -551,7 +551,7 @@ IFileDialogEvents *QWindowsNativeFileDialogEventHandler::create(QWindowsNativeFi class QWindowsShellItem { public: - typedef std::vector<IShellItem *> IShellItems; + using IShellItems = std::vector<IShellItem *>; explicit QWindowsShellItem(IShellItem *item); @@ -736,7 +736,7 @@ QString QWindowsShellItem::libraryItemDefaultSaveFolder(IShellItem *item) #ifndef QT_NO_DEBUG_STREAM void QWindowsShellItem::format(QDebug &d) const { - d << "attributes=0x" << hex << attributes() << dec; + d << "attributes=0x" << Qt::hex << attributes() << Qt::dec; if (isFileSystem()) d << " [filesys]"; if (isDir()) @@ -972,7 +972,7 @@ void QWindowsNativeFileDialogBase::doExec(HWND owner) // gets a WM_CLOSE or the parent window is destroyed. const HRESULT hr = m_fileDialog->Show(owner); QWindowsDialogs::eatMouseMove(); - qCDebug(lcQpaDialogs) << '<' << __FUNCTION__ << " returns " << hex << hr; + qCDebug(lcQpaDialogs) << '<' << __FUNCTION__ << " returns " << Qt::hex << hr; // Emit accepted() only if there is a result as otherwise UI hangs occur. // For example, typing in invalid URLs results in empty result lists. if (hr == S_OK && !m_data.selectedFiles().isEmpty()) { @@ -1013,7 +1013,7 @@ void QWindowsNativeFileDialogBase::setMode(QFileDialogOptions::FileMode mode, } qCDebug(lcQpaDialogs) << __FUNCTION__ << "mode=" << mode << "acceptMode=" << acceptMode << "options=" << options - << "results in" << showbase << hex << flags; + << "results in" << Qt::showbase << Qt::hex << flags; if (FAILED(m_fileDialog->SetOptions(flags))) qErrnoWarning("%s: SetOptions() failed", __FUNCTION__); @@ -1112,7 +1112,7 @@ void QWindowsNativeFileDialogBase::setDefaultSuffixSys(const QString &s) // If this parameter is non-empty, it will be appended by the dialog for the 'Any files' // filter ('*'). If this parameter is non-empty and the current filter has a suffix, // the dialog will append the filter's suffix. - wchar_t *wSuffix = const_cast<wchar_t *>(reinterpret_cast<const wchar_t *>(s.utf16())); + auto *wSuffix = const_cast<wchar_t *>(reinterpret_cast<const wchar_t *>(s.utf16())); m_fileDialog->SetDefaultExtension(wSuffix); } @@ -1125,7 +1125,7 @@ static inline IFileDialog2 *getFileDialog2(IFileDialog *fileDialog) void QWindowsNativeFileDialogBase::setLabelText(QFileDialogOptions::DialogLabel l, const QString &text) { - wchar_t *wText = const_cast<wchar_t *>(reinterpret_cast<const wchar_t *>(text.utf16())); + auto *wText = const_cast<wchar_t *>(reinterpret_cast<const wchar_t *>(text.utf16())); switch (l) { case QFileDialogOptions::FileName: m_fileDialog->SetFileNameLabel(wText); @@ -1688,7 +1688,7 @@ class QWindowsXpNativeFileDialog : public QWindowsNativeDialogBase { Q_OBJECT public: - typedef QSharedPointer<QFileDialogOptions> OptionsPtr; + using OptionsPtr = QSharedPointer<QFileDialogOptions>; static QWindowsXpNativeFileDialog *create(const OptionsPtr &options, const QWindowsFileDialogSharedData &data); @@ -1770,7 +1770,7 @@ void QWindowsXpNativeFileDialog::doExec(HWND owner) static int QT_WIN_CALLBACK xpFileDialogGetExistingDirCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData) { - QWindowsXpNativeFileDialog *dialog = reinterpret_cast<QWindowsXpNativeFileDialog *>(lpData); + auto *dialog = reinterpret_cast<QWindowsXpNativeFileDialog *>(lpData); return dialog->existingDirCallback(hwnd, uMsg, lParam); } @@ -1779,7 +1779,7 @@ static int QT_WIN_CALLBACK xpFileDialogGetExistingDirCallbackProc(HWND hwnd, UIN #if defined(Q_CC_MINGW) && (!defined(__MINGW64_VERSION_MAJOR) || __MINGW64_VERSION_MAJOR < 3) typedef ITEMIDLIST *qt_LpItemIdList; #else -typedef PIDLIST_ABSOLUTE qt_LpItemIdList; +using qt_LpItemIdList = PIDLIST_ABSOLUTE; #endif int QWindowsXpNativeFileDialog::existingDirCallback(HWND hwnd, UINT uMsg, LPARAM lParam) @@ -1843,7 +1843,7 @@ void QWindowsXpNativeFileDialog::populateOpenFileName(OPENFILENAME *ofn, HWND ow const QList<FilterSpec> specs = filterSpecs(m_options->nameFilters(), m_options->options() & QFileDialogOptions::HideNameFilterDetails, &totalStringLength); const int size = specs.size(); - wchar_t *ptr = new wchar_t[totalStringLength + 2 * size + 1]; + auto *ptr = new wchar_t[totalStringLength + 2 * size + 1]; ofn->lpstrFilter = ptr; for (const FilterSpec &spec : specs) { ptr += spec.description.toWCharArray(ptr); @@ -2007,7 +2007,7 @@ QString QWindowsXpFileDialogHelper::selectedNameFilter() const \ingroup qt-lighthouse-win */ -typedef QSharedPointer<QColor> SharedPointerColor; +using SharedPointerColor = QSharedPointer<QColor>; #ifdef USE_NATIVE_COLOR_DIALOG class QWindowsNativeColorDialog : public QWindowsNativeDialogBase diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.h b/src/plugins/platforms/windows/qwindowsdialoghelpers.h index 6099ea9ac6..8686749011 100644 --- a/src/plugins/platforms/windows/qwindowsdialoghelpers.h +++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.h @@ -64,9 +64,9 @@ namespace QWindowsDialogs template <class BaseClass> class QWindowsDialogHelperBase : public BaseClass { - Q_DISABLE_COPY(QWindowsDialogHelperBase) + Q_DISABLE_COPY_MOVE(QWindowsDialogHelperBase) public: - typedef QSharedPointer<QWindowsNativeDialogBase> QWindowsNativeDialogBasePtr; + using QWindowsNativeDialogBasePtr = QSharedPointer<QWindowsNativeDialogBase>; ~QWindowsDialogHelperBase() { cleanupThread(); } void exec() override; @@ -75,7 +75,7 @@ public: QWindow *parent) override; void hide() override; - virtual bool supportsNonModalDialog(const QWindow * /* parent */ = 0) const { return true; } + virtual bool supportsNonModalDialog(const QWindow * /* parent */ = nullptr) const { return true; } protected: QWindowsDialogHelperBase() = default; @@ -91,7 +91,7 @@ private: void cleanupThread(); QWindowsNativeDialogBasePtr m_nativeDialog; - HWND m_ownerWindow = 0; + HWND m_ownerWindow = nullptr; int m_timerId = 0; QThread *m_thread = nullptr; }; diff --git a/src/plugins/platforms/windows/qwindowsdrag.cpp b/src/plugins/platforms/windows/qwindowsdrag.cpp index 322865b0f3..3e4c93d47a 100644 --- a/src/plugins/platforms/windows/qwindowsdrag.cpp +++ b/src/plugins/platforms/windows/qwindowsdrag.cpp @@ -428,7 +428,7 @@ QWindowsOleDropSource::QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState) if (QWindowsContext::verbose > 1 || result != S_OK) { qCDebug(lcQpaMime) << __FUNCTION__ << "fEscapePressed=" << fEscapePressed << "grfKeyState=" << grfKeyState << "buttons" << m_currentButtons - << "returns 0x" << hex << int(result) << dec; + << "returns 0x" << Qt::hex << int(result) << Qt::dec; } return ResultFromScode(result); } @@ -627,7 +627,7 @@ QWindowsOleDropTarget::Drop(LPDATAOBJECT pDataObj, DWORD grfKeyState, m_chosenEffect = DROPEFFECT_COPY; HGLOBAL hData = GlobalAlloc(0, sizeof(DWORD)); if (hData) { - DWORD *moveEffect = reinterpret_cast<DWORD *>(GlobalLock(hData)); + auto *moveEffect = reinterpret_cast<DWORD *>(GlobalLock(hData)); *moveEffect = DROPEFFECT_MOVE; GlobalUnlock(hData); STGMEDIUM medium; @@ -704,13 +704,13 @@ Qt::DropAction QWindowsDrag::drag(QDrag *drag) DWORD resultEffect; QWindowsDrag::m_canceled = false; - QWindowsOleDropSource *windowDropSource = new QWindowsOleDropSource(this); + auto *windowDropSource = new QWindowsOleDropSource(this); windowDropSource->createCursors(); - QWindowsDropDataObject *dropDataObject = new QWindowsDropDataObject(dropData); + auto *dropDataObject = new QWindowsDropDataObject(dropData); const Qt::DropActions possibleActions = drag->supportedActions(); const DWORD allowedEffects = translateToWinDragEffects(possibleActions); qCDebug(lcQpaMime) << '>' << __FUNCTION__ << "possible Actions=0x" - << hex << int(possibleActions) << "effects=0x" << allowedEffects << dec; + << Qt::hex << int(possibleActions) << "effects=0x" << allowedEffects << Qt::dec; // Indicate message handlers we are in DoDragDrop() event loop. QWindowsDrag::m_dragging = true; const HRESULT r = DoDragDrop(dropDataObject, windowDropSource, allowedEffects, &resultEffect); @@ -734,9 +734,9 @@ Qt::DropAction QWindowsDrag::drag(QDrag *drag) dropDataObject->releaseQt(); dropDataObject->Release(); // Will delete obj if refcount becomes 0 windowDropSource->Release(); // Will delete src if refcount becomes 0 - qCDebug(lcQpaMime) << '<' << __FUNCTION__ << hex << "allowedEffects=0x" << allowedEffects + qCDebug(lcQpaMime) << '<' << __FUNCTION__ << Qt::hex << "allowedEffects=0x" << allowedEffects << "reportedPerformedEffect=0x" << reportedPerformedEffect - << " resultEffect=0x" << resultEffect << "hr=0x" << int(r) << dec << "dropAction=" << dragResult; + << " resultEffect=0x" << resultEffect << "hr=0x" << int(r) << Qt::dec << "dropAction=" << dragResult; return dragResult; } diff --git a/src/plugins/platforms/windows/qwindowseglcontext.cpp b/src/plugins/platforms/windows/qwindowseglcontext.cpp index 063e81150e..e9f3dc5189 100644 --- a/src/plugins/platforms/windows/qwindowseglcontext.cpp +++ b/src/plugins/platforms/windows/qwindowseglcontext.cpp @@ -469,10 +469,10 @@ bool QWindowsEGLContext::makeCurrent(QPlatformSurface *surface) QWindowsEGLStaticContext::libEGL.eglBindAPI(m_api); - QWindowsWindow *window = static_cast<QWindowsWindow *>(surface); + auto *window = static_cast<QWindowsWindow *>(surface); window->aboutToMakeCurrent(); int err = 0; - EGLSurface eglSurface = static_cast<EGLSurface>(window->surface(m_eglConfig, &err)); + auto eglSurface = static_cast<EGLSurface>(window->surface(m_eglConfig, &err)); if (eglSurface == EGL_NO_SURFACE) { if (err == EGL_CONTEXT_LOST) { m_eglContext = EGL_NO_CONTEXT; @@ -531,9 +531,9 @@ void QWindowsEGLContext::doneCurrent() void QWindowsEGLContext::swapBuffers(QPlatformSurface *surface) { QWindowsEGLStaticContext::libEGL.eglBindAPI(m_api); - QWindowsWindow *window = static_cast<QWindowsWindow *>(surface); + auto *window = static_cast<QWindowsWindow *>(surface); int err = 0; - EGLSurface eglSurface = static_cast<EGLSurface>(window->surface(m_eglConfig, &err)); + auto eglSurface = static_cast<EGLSurface>(window->surface(m_eglConfig, &err)); if (eglSurface == EGL_NO_SURFACE) { if (err == EGL_CONTEXT_LOST) { m_eglContext = EGL_NO_CONTEXT; diff --git a/src/plugins/platforms/windows/qwindowseglcontext.h b/src/plugins/platforms/windows/qwindowseglcontext.h index 8a1e1ddae8..d96e266159 100644 --- a/src/plugins/platforms/windows/qwindowseglcontext.h +++ b/src/plugins/platforms/windows/qwindowseglcontext.h @@ -109,7 +109,7 @@ private: class QWindowsEGLStaticContext : public QWindowsStaticOpenGLContext { - Q_DISABLE_COPY(QWindowsEGLStaticContext) + Q_DISABLE_COPY_MOVE(QWindowsEGLStaticContext) public: static QWindowsEGLStaticContext *create(QWindowsOpenGLTester::Renderers preferredType); diff --git a/src/plugins/platforms/windows/qwindowsgdinativeinterface.cpp b/src/plugins/platforms/windows/qwindowsgdinativeinterface.cpp index 08e11c5e39..f2418b0e60 100644 --- a/src/plugins/platforms/windows/qwindowsgdinativeinterface.cpp +++ b/src/plugins/platforms/windows/qwindowsgdinativeinterface.cpp @@ -50,7 +50,7 @@ void *QWindowsGdiNativeInterface::nativeResourceForBackingStore(const QByteArray qWarning("%s: '%s' requested for null backingstore or backingstore without handle.", __FUNCTION__, resource.constData()); return nullptr; } - QWindowsBackingStore *wbs = static_cast<QWindowsBackingStore *>(bs->handle()); + auto *wbs = static_cast<QWindowsBackingStore *>(bs->handle()); if (resource == "getDC") return wbs->getDC(); qWarning("%s: Invalid key '%s' requested.", __FUNCTION__, resource.constData()); diff --git a/src/plugins/platforms/windows/qwindowsglcontext.cpp b/src/plugins/platforms/windows/qwindowsglcontext.cpp index 50f528e7fc..8bf88300e9 100644 --- a/src/plugins/platforms/windows/qwindowsglcontext.cpp +++ b/src/plugins/platforms/windows/qwindowsglcontext.cpp @@ -243,7 +243,7 @@ QDebug operator<<(QDebug d, const PIXELFORMATDESCRIPTOR &pd) QDebugStateSaver saver(d); d.nospace(); d << "PIXELFORMATDESCRIPTOR " - << "dwFlags=" << hex << showbase << pd.dwFlags << dec << noshowbase; + << "dwFlags=" << Qt::hex << Qt::showbase << pd.dwFlags << Qt::dec << Qt::noshowbase; if (pd.dwFlags & PFD_DRAW_TO_WINDOW) d << " PFD_DRAW_TO_WINDOW"; if (pd.dwFlags & PFD_DRAW_TO_BITMAP) d << " PFD_DRAW_TO_BITMAP"; if (pd.dwFlags & PFD_SUPPORT_GDI) d << " PFD_SUPPORT_GDI"; @@ -631,10 +631,10 @@ static int choosePixelFormat(HDC hdc, nsp << __FUNCTION__; if (sampleBuffersRequested) nsp << " samples=" << iAttributes[samplesValuePosition]; - nsp << " Attributes: " << hex << showbase; + nsp << " Attributes: " << Qt::hex << Qt::showbase; for (int ii = 0; ii < i; ++ii) nsp << iAttributes[ii] << ','; - nsp << noshowbase << dec << "\n obtained px #" << pixelFormat + nsp << Qt::noshowbase << Qt::dec << "\n obtained px #" << pixelFormat << " of " << numFormats << "\n " << *obtainedPfd; qCDebug(lcQpaGl) << message; } // Debug @@ -784,7 +784,7 @@ static HGLRC createContext(const QOpenGLStaticContext &staticContext, if (!result) { QString message; QDebug(&message).nospace() << __FUNCTION__ << ": wglCreateContextAttribsARB() failed (GL error code: 0x" - << hex << staticContext.opengl32.glGetError() << dec << ") for format: " << format << ", shared context: " << shared; + << Qt::hex << staticContext.opengl32.glGetError() << Qt::dec << ") for format: " << format << ", shared context: " << shared; qErrnoWarning("%s", qPrintable(message)); } return result; @@ -912,7 +912,7 @@ void QWindowsOpenGLContextFormat::apply(QSurfaceFormat *format) const class QOpenGLTemporaryContext { - Q_DISABLE_COPY(QOpenGLTemporaryContext) + Q_DISABLE_COPY_MOVE(QOpenGLTemporaryContext) public: QOpenGLTemporaryContext(); ~QOpenGLTemporaryContext(); @@ -1028,7 +1028,7 @@ QOpenGLStaticContext *QOpenGLStaticContext::create(bool softwareRendering) QScopedPointer<QOpenGLTemporaryContext> temporaryContext; if (!QOpenGLStaticContext::opengl32.wglGetCurrentContext()) temporaryContext.reset(new QOpenGLTemporaryContext); - QOpenGLStaticContext *result = new QOpenGLStaticContext; + auto *result = new QOpenGLStaticContext; qCDebug(lcQpaGl) << __FUNCTION__ << *result; return result; } @@ -1070,7 +1070,7 @@ QWindowsGLContext::QWindowsGLContext(QOpenGLStaticContext *staticContext, qWarning("QWindowsGLContext: Requires a QWGLNativeContext"); return; } - QWGLNativeContext handle = nativeHandle.value<QWGLNativeContext>(); + auto handle = nativeHandle.value<QWGLNativeContext>(); HGLRC wglcontext = handle.context(); HWND wnd = handle.window(); if (!wglcontext || !wnd) { @@ -1308,7 +1308,7 @@ bool QWindowsGLContext::makeCurrent(QPlatformSurface *surface) Q_ASSERT(surface->surface()->supportsOpenGL()); // Do we already have a DC entry for that window? - QWindowsWindow *window = static_cast<QWindowsWindow *>(surface); + auto *window = static_cast<QWindowsWindow *>(surface); window->aboutToMakeCurrent(); const HWND hwnd = window->handle(); if (const QOpenGLContextData *contextData = findByHWND(m_windowContexts, hwnd)) { @@ -1377,7 +1377,7 @@ QFunctionPointer QWindowsGLContext::getProcAddress(const char *procName) // Even though we use QFunctionPointer, it does not mean the function can be called. // It will need to be cast to the proper function type with the correct calling // convention. QFunctionPointer is nothing more than a glorified void* here. - QFunctionPointer procAddress = reinterpret_cast<QFunctionPointer>(QOpenGLStaticContext::opengl32.wglGetProcAddress(procName)); + auto procAddress = reinterpret_cast<QFunctionPointer>(QOpenGLStaticContext::opengl32.wglGetProcAddress(procName)); // We support AllGLFunctionsQueryable, which means this function must be able to // return a function pointer even for functions that are in GL.h and exported diff --git a/src/plugins/platforms/windows/qwindowsglcontext.h b/src/plugins/platforms/windows/qwindowsglcontext.h index 00e4d323a6..8b0c33f7d5 100644 --- a/src/plugins/platforms/windows/qwindowsglcontext.h +++ b/src/plugins/platforms/windows/qwindowsglcontext.h @@ -75,9 +75,9 @@ struct QOpenGLContextData QOpenGLContextData(HGLRC r, HWND h, HDC d) : renderingContext(r), hwnd(h), hdc(d) {} QOpenGLContextData() {} - HGLRC renderingContext = 0; - HWND hwnd = 0; - HDC hdc = 0; + HGLRC renderingContext = nullptr; + HWND hwnd = nullptr; + HDC hdc = nullptr; }; class QOpenGLStaticContext; @@ -89,7 +89,7 @@ struct QWindowsOpenGLContextFormat QSurfaceFormat::OpenGLContextProfile profile = QSurfaceFormat::NoProfile; int version = 0; //! majorVersion<<8 + minorVersion - QSurfaceFormat::FormatOptions options = 0; + QSurfaceFormat::FormatOptions options = nullptr; }; #ifndef QT_NO_DEBUG_STREAM @@ -134,7 +134,7 @@ private: class QOpenGLStaticContext : public QWindowsStaticOpenGLContext { - Q_DISABLE_COPY(QOpenGLStaticContext) + Q_DISABLE_COPY_MOVE(QOpenGLStaticContext) QOpenGLStaticContext(); public: enum Extensions @@ -223,7 +223,7 @@ private: typedef GLenum (APIENTRY *GlGetGraphicsResetStatusArbType)(); inline void releaseDCs(); - bool updateObtainedParams(HDC hdc, int *obtainedSwapInterval = 0); + bool updateObtainedParams(HDC hdc, int *obtainedSwapInterval = nullptr); QOpenGLStaticContext *m_staticContext; QOpenGLContext *m_context; diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.cpp b/src/plugins/platforms/windows/qwindowsinputcontext.cpp index 8054f9fe83..d5258ca6a3 100644 --- a/src/plugins/platforms/windows/qwindowsinputcontext.cpp +++ b/src/plugins/platforms/windows/qwindowsinputcontext.cpp @@ -664,9 +664,9 @@ void QWindowsInputContext::handleInputLanguageChanged(WPARAM wparam, LPARAM lpar m_locale = qt_localeFromLCID(m_languageId); emitLocaleChanged(); - qCDebug(lcQpaInputMethods) << __FUNCTION__ << hex << showbase + qCDebug(lcQpaInputMethods) << __FUNCTION__ << Qt::hex << Qt::showbase << oldLanguageId << "->" << newLanguageId << "Character set:" - << DWORD(wparam) << dec << noshowbase << m_locale; + << DWORD(wparam) << Qt::dec << Qt::noshowbase << m_locale; } /*! @@ -724,7 +724,7 @@ int QWindowsInputContext::reconvertString(RECONVERTSTRING *reconv) reconv->dwCompStrOffset = DWORD(startPos) * sizeof(ushort); // byte count. reconv->dwTargetStrLen = reconv->dwCompStrLen; reconv->dwTargetStrOffset = reconv->dwCompStrOffset; - ushort *pastReconv = reinterpret_cast<ushort *>(reconv + 1); + auto *pastReconv = reinterpret_cast<ushort *>(reconv + 1); std::copy(surroundingText.utf16(), surroundingText.utf16() + surroundingText.size(), QT_MAKE_UNCHECKED_ARRAY_ITERATOR(pastReconv)); return memSize; diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.h b/src/plugins/platforms/windows/qwindowsinputcontext.h index a47585c29e..857706bcb9 100644 --- a/src/plugins/platforms/windows/qwindowsinputcontext.h +++ b/src/plugins/platforms/windows/qwindowsinputcontext.h @@ -53,12 +53,12 @@ class QWindowsWindow; class QWindowsInputContext : public QPlatformInputContext { - Q_DISABLE_COPY(QWindowsInputContext) + Q_DISABLE_COPY_MOVE(QWindowsInputContext) Q_OBJECT struct CompositionContext { - HWND hwnd = 0; + HWND hwnd = nullptr; QString composition; int position = 0; bool isComposing = false; diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp index 5c1fa00088..eccf1c4928 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.cpp +++ b/src/plugins/platforms/windows/qwindowsintegration.cpp @@ -133,7 +133,7 @@ QT_BEGIN_NAMESPACE struct QWindowsIntegrationPrivate { - Q_DISABLE_COPY(QWindowsIntegrationPrivate) + Q_DISABLE_COPY_MOVE(QWindowsIntegrationPrivate) explicit QWindowsIntegrationPrivate(const QStringList ¶mList); ~QWindowsIntegrationPrivate(); @@ -217,6 +217,8 @@ static inline unsigned parseOptions(const QStringList ¶mList, options |= QWindowsIntegration::NoNativeMenus; } else if (param == QLatin1String("nowmpointer")) { options |= QWindowsIntegration::DontUseWMPointer; + } else if (param == QLatin1String("reverse")) { + options |= QWindowsIntegration::RtlEnabled; } else { qWarning() << "Unknown option" << param; } @@ -322,9 +324,9 @@ bool QWindowsIntegration::hasCapability(QPlatformIntegration::Capability cap) co QPlatformWindow *QWindowsIntegration::createPlatformWindow(QWindow *window) const { if (window->type() == Qt::Desktop) { - QWindowsDesktopWindow *result = new QWindowsDesktopWindow(window); + auto *result = new QWindowsDesktopWindow(window); qCDebug(lcQpaWindows) << "Desktop window:" << window - << showbase << hex << result->winId() << noshowbase << dec << result->geometry(); + << Qt::showbase << Qt::hex << result->winId() << Qt::noshowbase << Qt::dec << result->geometry(); return result; } @@ -369,15 +371,15 @@ QPlatformWindow *QWindowsIntegration::createForeignWindow(QWindow *window, WId n qWarning("Windows QPA: Invalid foreign window ID %p.", hwnd); return nullptr; } - QWindowsForeignWindow *result = new QWindowsForeignWindow(window, hwnd); + auto *result = new QWindowsForeignWindow(window, hwnd); const QRect obtainedGeometry = result->geometry(); QScreen *screen = nullptr; if (const QPlatformScreen *pScreen = result->screenForGeometry(obtainedGeometry)) screen = pScreen->screen(); if (screen && screen != window->screen()) window->setScreen(screen); - qCDebug(lcQpaWindows) << "Foreign window:" << window << showbase << hex - << result->winId() << noshowbase << dec << obtainedGeometry << screen; + qCDebug(lcQpaWindows) << "Foreign window:" << window << Qt::showbase << Qt::hex + << result->winId() << Qt::noshowbase << Qt::dec << obtainedGeometry << screen; return result; } diff --git a/src/plugins/platforms/windows/qwindowsintegration.h b/src/plugins/platforms/windows/qwindowsintegration.h index e28b2c2fb3..b49d21022b 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.h +++ b/src/plugins/platforms/windows/qwindowsintegration.h @@ -54,7 +54,7 @@ class QWindowsStaticOpenGLContext; class QWindowsIntegration : public QPlatformIntegration { - Q_DISABLE_COPY(QWindowsIntegration) + Q_DISABLE_COPY_MOVE(QWindowsIntegration) public: enum Options { // Options to be passed on command line. FontDatabaseFreeType = 0x1, @@ -69,7 +69,8 @@ public: AlwaysUseNativeMenus = 0x100, NoNativeMenus = 0x200, DontUseWMPointer = 0x400, - DetectAltGrModifier = 0x800 + DetectAltGrModifier = 0x800, + RtlEnabled = 0x1000 }; explicit QWindowsIntegration(const QStringList ¶mList); diff --git a/src/plugins/platforms/windows/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp index da630005d6..4f0f846749 100644 --- a/src/plugins/platforms/windows/qwindowskeymapper.cpp +++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp @@ -100,7 +100,7 @@ QWindowsKeyMapper::QWindowsKeyMapper() : m_useRTLExtensions(false), m_keyGrabber(nullptr) { memset(keyLayout, 0, sizeof(keyLayout)); - QGuiApplication *app = static_cast<QGuiApplication *>(QGuiApplication::instance()); + auto *app = static_cast<QGuiApplication *>(QGuiApplication::instance()); QObject::connect(app, &QGuiApplication::applicationStateChanged, app, clearKeyRecorderOnApplicationInActive); changeKeyboard(); @@ -554,7 +554,7 @@ QDebug operator<<(QDebug d, const KeyboardLayoutItem &k) if (const quint32 qtKey = k.qtKey[i]) { d << '[' << i << ' '; QtDebugUtils::formatQFlags(d, ModsTbl[i]); - d << ' ' << hex << showbase << qtKey << dec << noshowbase << ' '; + d << ' ' << Qt::hex << Qt::showbase << qtKey << Qt::dec << Qt::noshowbase << ' '; QtDebugUtils::formatQEnum(d, Qt::Key(qtKey)); if (qtKey >= 32 && qtKey < 128) d << " '" << char(qtKey) << '\''; @@ -776,7 +776,7 @@ void QWindowsKeyMapper::updatePossibleKeyCodes(unsigned char *kbdBuffer, quint32 ::ToAscii(vk_key, scancode, kbdBuffer, reinterpret_cast<LPWORD>(&buffer), 0); } qCDebug(lcQpaEvents) << __FUNCTION__ << "for virtual key=" - << hex << showbase << vk_key << dec << noshowbase << keyLayout[vk_key]; + << Qt::hex << Qt::showbase << vk_key << Qt::dec << Qt::noshowbase << keyLayout[vk_key]; } static inline QString messageKeyText(const MSG &msg) @@ -950,7 +950,7 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, MSG msg, const UINT msgType = msg.message; const quint32 scancode = (msg.lParam >> 16) & scancodeBitmask; - quint32 vk_key = quint32(msg.wParam); + auto vk_key = quint32(msg.wParam); quint32 nModifiers = 0; QWindow *receiver = m_keyGrabber ? m_keyGrabber : window; @@ -1182,7 +1182,7 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, MSG msg, // results, if we map this virtual key-code directly (for eg '?' US layouts). So try // to find the correct key using the current message parameters & keyboard state. if (uch.isNull() && msgType == WM_IME_KEYDOWN) { - const QWindowsInputContext *windowsInputContext = + const auto *windowsInputContext = qobject_cast<const QWindowsInputContext *>(QWindowsIntegration::instance()->inputContext()); if (!(windowsInputContext && windowsInputContext->isComposing())) vk_key = ImmGetVirtualKey(reinterpret_cast<HWND>(window->winId())); @@ -1400,7 +1400,7 @@ QList<int> QWindowsKeyMapper::possibleKeys(const QKeyEvent *e) const } } qCDebug(lcQpaEvents) << __FUNCTION__ << e << "nativeVirtualKey=" - << showbase << hex << e->nativeVirtualKey() << dec << noshowbase + << Qt::showbase << Qt::hex << e->nativeVirtualKey() << Qt::dec << Qt::noshowbase << e->modifiers() << kbItem << "\n returns" << formatKeys(result); return result; } diff --git a/src/plugins/platforms/windows/qwindowskeymapper.h b/src/plugins/platforms/windows/qwindowskeymapper.h index a454f0f973..b1ada1d373 100644 --- a/src/plugins/platforms/windows/qwindowskeymapper.h +++ b/src/plugins/platforms/windows/qwindowskeymapper.h @@ -71,7 +71,7 @@ struct KeyboardLayoutItem { class QWindowsKeyMapper { - Q_DISABLE_COPY(QWindowsKeyMapper) + Q_DISABLE_COPY_MOVE(QWindowsKeyMapper) public: explicit QWindowsKeyMapper(); ~QWindowsKeyMapper(); diff --git a/src/plugins/platforms/windows/qwindowsmenu.cpp b/src/plugins/platforms/windows/qwindowsmenu.cpp index 5a92a7cf90..d20edd685e 100644 --- a/src/plugins/platforms/windows/qwindowsmenu.cpp +++ b/src/plugins/platforms/windows/qwindowsmenu.cpp @@ -518,7 +518,7 @@ QWindowsMenu::~QWindowsMenu() void QWindowsMenu::insertMenuItem(QPlatformMenuItem *menuItemIn, QPlatformMenuItem *before) { qCDebug(lcQpaMenus) << __FUNCTION__ << '(' << menuItemIn << ", before=" << before << ')' << this; - QWindowsMenuItem *menuItem = static_cast<QWindowsMenuItem *>(menuItemIn); + auto *menuItem = static_cast<QWindowsMenuItem *>(menuItemIn); const int index = insertBefore(&m_menuItems, menuItemIn, before); const bool append = index == m_menuItems.size() - 1; menuItem->insertIntoMenu(this, append, index); @@ -689,7 +689,7 @@ void QWindowsPopupMenu::showPopup(const QWindow *parentWindow, const QRect &targ const QPlatformMenuItem *item) { qCDebug(lcQpaMenus) << __FUNCTION__ << '>' << this << parentWindow << targetRect << item; - const QWindowsBaseWindow *window = static_cast<const QWindowsBaseWindow *>(parentWindow->handle()); + const auto *window = static_cast<const QWindowsBaseWindow *>(parentWindow->handle()); const QPoint globalPos = window->mapToGlobal(targetRect.topLeft()); trackPopupMenu(window->handle(), globalPos.x(), globalPos.y()); } @@ -756,7 +756,7 @@ QWindowsMenuBar::~QWindowsMenuBar() void QWindowsMenuBar::insertMenu(QPlatformMenu *menuIn, QPlatformMenu *before) { qCDebug(lcQpaMenus) << __FUNCTION__ << menuIn << "before=" << before; - QWindowsMenu *menu = static_cast<QWindowsMenu *>(menuIn); + auto *menu = static_cast<QWindowsMenu *>(menuIn); const int index = insertBefore(&m_menus, menuIn, before); menu->insertIntoMenuBar(this, index == m_menus.size() - 1, index); } @@ -784,7 +784,7 @@ void QWindowsMenuBar::handleReparent(QWindow *newParentWindow) if (QPlatformWindow *platWin = newParentWindow->handle()) install(static_cast<QWindowsWindow *>(platWin)); else // Store for later creation, see menuBarOf() - newParentWindow->setProperty(menuBarPropertyName, qVariantFromValue<QObject *>(this)); + newParentWindow->setProperty(menuBarPropertyName, QVariant::fromValue<QObject *>(this)); } QWindowsMenuBar *QWindowsMenuBar::menuBarOf(const QWindow *notYetCreatedWindow) @@ -896,8 +896,8 @@ void QWindowsMenuItem::formatDebug(QDebug &d) const d << ", parentMenu=" << static_cast<const void *>(m_parentMenu); if (m_subMenu) d << ", subMenu=" << static_cast<const void *>(m_subMenu); - d << ", tag=" << showbase << hex - << tag() << noshowbase << dec << ", id=" << m_id; + d << ", tag=" << Qt::showbase << Qt::hex + << tag() << Qt::noshowbase << Qt::dec << ", id=" << m_id; #if QT_CONFIG(shortcut) if (!m_shortcut.isEmpty()) d << ", shortcut=" << m_shortcut; @@ -933,7 +933,7 @@ void QWindowsMenu::formatDebug(QDebug &d) const if (m_parentMenu != nullptr) d << " [on menu]"; if (tag()) - d << ", tag=" << showbase << hex << tag() << noshowbase << dec; + d << ", tag=" << Qt::showbase << Qt::hex << tag() << Qt::noshowbase << Qt::dec; if (m_visible) d << " [visible]"; if (m_enabled) diff --git a/src/plugins/platforms/windows/qwindowsmenu.h b/src/plugins/platforms/windows/qwindowsmenu.h index 6de1553f35..aa36846ec0 100644 --- a/src/plugins/platforms/windows/qwindowsmenu.h +++ b/src/plugins/platforms/windows/qwindowsmenu.h @@ -120,7 +120,7 @@ class QWindowsMenu : public QPlatformMenu { Q_OBJECT public: - typedef QVector<QWindowsMenuItem *> MenuItems; + using MenuItems = QVector<QWindowsMenuItem *>; QWindowsMenu(); ~QWindowsMenu(); @@ -196,7 +196,7 @@ class QWindowsMenuBar : public QPlatformMenuBar { Q_OBJECT public: - typedef QVector<QWindowsMenu *> Menus; + using Menus = QVector<QWindowsMenu *>; QWindowsMenuBar(); ~QWindowsMenuBar() override; diff --git a/src/plugins/platforms/windows/qwindowsmime.cpp b/src/plugins/platforms/windows/qwindowsmime.cpp index 030d8d1e0f..b9d8b191f5 100644 --- a/src/plugins/platforms/windows/qwindowsmime.cpp +++ b/src/plugins/platforms/windows/qwindowsmime.cpp @@ -178,7 +178,7 @@ static bool qt_write_dibv5(QDataStream &s, QImage image) if (image.format() != QImage::Format_ARGB32) image = image.convertToFormat(QImage::Format_ARGB32); - uchar *buf = new uchar[bpl_bmp]; + auto *buf = new uchar[bpl_bmp]; memset(buf, 0, size_t(bpl_bmp)); for (int y=image.height()-1; y>=0; y--) { @@ -264,7 +264,7 @@ static bool qt_read_dibv5(QDataStream &s, QImage &image) const int bpl = image.bytesPerLine(); uchar *data = image.bits(); - uchar *buf24 = new uchar[bpl]; + auto *buf24 = new uchar[bpl]; const int bpl24 = ((w * nbits + 31) / 32) * 4; while (--h >= 0) { @@ -286,7 +286,7 @@ static bool qt_read_dibv5(QDataStream &s, QImage &image) if (bi.bV5Height < 0) { // Flip the image - uchar *buf = new uchar[bpl]; + auto *buf = new uchar[bpl]; h = -bi.bV5Height; for (int y = 0; y < h/2; ++y) { memcpy(buf, data + y * bpl, size_t(bpl)); @@ -772,16 +772,16 @@ bool QWindowsMimeURI::convertFromMime(const FORMATETC &formatetc, const QMimeDat } QByteArray result(size, '\0'); - DROPFILES* d = reinterpret_cast<DROPFILES *>(result.data()); + auto* d = reinterpret_cast<DROPFILES *>(result.data()); d->pFiles = sizeof(DROPFILES); GetCursorPos(&d->pt); // try d->fNC = true; char *files = (reinterpret_cast<char*>(d)) + d->pFiles; d->fWide = true; - wchar_t *f = reinterpret_cast<wchar_t *>(files); + auto *f = reinterpret_cast<wchar_t *>(files); for (int i=0; i<fileNames.size(); i++) { - const size_t l = size_t(fileNames.at(i).length()); + const auto l = size_t(fileNames.at(i).length()); memcpy(f, fileNames.at(i).utf16(), l * sizeof(ushort)); f += l; *f++ = 0; @@ -852,9 +852,9 @@ QVariant QWindowsMimeURI::convertToMime(const QString &mimeType, LPDATAOBJECT pD if (data.isEmpty()) return QVariant(); - const DROPFILES *hdrop = reinterpret_cast<const DROPFILES *>(data.constData()); + const auto *hdrop = reinterpret_cast<const DROPFILES *>(data.constData()); if (hdrop->fWide) { - const wchar_t *filesw = reinterpret_cast<const wchar_t *>(data.constData() + hdrop->pFiles); + const auto *filesw = reinterpret_cast<const wchar_t *>(data.constData() + hdrop->pFiles); int i = 0; while (filesw[i]) { QString fileurl = QString::fromWCharArray(filesw + i); @@ -1055,7 +1055,7 @@ QVector<FORMATETC> QWindowsMimeImage::formatsForMime(const QString &mimeType, co QVector<FORMATETC> formatetcs; if (mimeData->hasImage() && mimeType == QLatin1String("application/x-qt-image")) { //add DIBV5 if image has alpha channel. Do not add CF_PNG here as it will confuse MS Office (QTBUG47656). - QImage image = qvariant_cast<QImage>(mimeData->imageData()); + auto image = qvariant_cast<QImage>(mimeData->imageData()); if (!image.isNull() && image.hasAlphaChannel()) formatetcs += setCf(CF_DIBV5); formatetcs += setCf(CF_DIB); @@ -1097,7 +1097,7 @@ bool QWindowsMimeImage::convertFromMime(const FORMATETC &formatetc, const QMimeD { int cf = getCf(formatetc); if ((cf == CF_DIB || cf == CF_DIBV5 || cf == int(CF_PNG)) && mimeData->hasImage()) { - QImage img = qvariant_cast<QImage>(mimeData->imageData()); + auto img = qvariant_cast<QImage>(mimeData->imageData()); if (img.isNull()) return false; QByteArray ba; diff --git a/src/plugins/platforms/windows/qwindowsmime.h b/src/plugins/platforms/windows/qwindowsmime.h index 6bbbae1a0e..1c389e8800 100644 --- a/src/plugins/platforms/windows/qwindowsmime.h +++ b/src/plugins/platforms/windows/qwindowsmime.h @@ -53,7 +53,7 @@ class QMimeData; class QWindowsMime { - Q_DISABLE_COPY(QWindowsMime) + Q_DISABLE_COPY_MOVE(QWindowsMime) public: QWindowsMime(); virtual ~QWindowsMime(); @@ -73,7 +73,7 @@ public: class QWindowsMimeConverter { - Q_DISABLE_COPY(QWindowsMimeConverter) + Q_DISABLE_COPY_MOVE(QWindowsMimeConverter) public: QWindowsMimeConverter(); ~QWindowsMimeConverter(); @@ -85,7 +85,7 @@ public: // Convenience. QVariant convertToMime(const QStringList &mimeTypes, IDataObject *pDataObj, QVariant::Type preferredType, - QString *format = 0) const; + QString *format = nullptr) const; void registerMime(QWindowsMime *mime); void unregisterMime(QWindowsMime *mime) { m_mimes.removeOne(mime); } diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.cpp b/src/plugins/platforms/windows/qwindowsmousehandler.cpp index e33591c33d..6df5e6aa27 100644 --- a/src/plugins/platforms/windows/qwindowsmousehandler.cpp +++ b/src/plugins/platforms/windows/qwindowsmousehandler.cpp @@ -106,7 +106,7 @@ static inline void compressMouseMove(MSG *msg) // Extract the x,y coordinates from the lParam as we do in the WndProc msg->pt.x = GET_X_LPARAM(mouseMsg.lParam); msg->pt.y = GET_Y_LPARAM(mouseMsg.lParam); - ClientToScreen(msg->hwnd, &(msg->pt)); + clientToScreen(msg->hwnd, &(msg->pt)); // Remove the mouse move message PeekMessage(&mouseMsg, msg->hwnd, WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE); @@ -124,10 +124,10 @@ static inline QTouchDevice *createTouchDevice() return nullptr; const int tabletPc = GetSystemMetrics(SM_TABLETPC); const int maxTouchPoints = GetSystemMetrics(SM_MAXIMUMTOUCHES); - qCDebug(lcQpaEvents) << "Digitizers:" << hex << showbase << (digitizers & ~NID_READY) - << "Ready:" << (digitizers & NID_READY) << dec << noshowbase + qCDebug(lcQpaEvents) << "Digitizers:" << Qt::hex << Qt::showbase << (digitizers & ~NID_READY) + << "Ready:" << (digitizers & NID_READY) << Qt::dec << Qt::noshowbase << "Tablet PC:" << tabletPc << "Max touch points:" << maxTouchPoints; - QTouchDevice *result = new QTouchDevice; + auto *result = new QTouchDevice; result->setType(digitizers & NID_INTEGRATED_TOUCH ? QTouchDevice::TouchScreen : QTouchDevice::TouchPad); QTouchDevice::Capabilities capabilities = QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::NormalizedPosition; @@ -268,7 +268,13 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd, if (et == QtWindows::MouseWheelEvent) return translateMouseWheelEvent(window, hwnd, msg, result); - const QPoint winEventPosition(GET_X_LPARAM(msg.lParam), GET_Y_LPARAM(msg.lParam)); + QPoint winEventPosition(GET_X_LPARAM(msg.lParam), GET_Y_LPARAM(msg.lParam)); + if ((et & QtWindows::NonClientEventFlag) == 0 && QWindowsBaseWindow::isRtlLayout(hwnd)) { + RECT clientArea; + GetClientRect(hwnd, &clientArea); + winEventPosition.setX(clientArea.right - winEventPosition.x()); + } + QPoint clientPosition; QPoint globalPosition; if (et & QtWindows::NonClientEventFlag) { @@ -300,7 +306,7 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd, // However, when tablet support is active, extraInfo is a packet serial number. This is not a problem // since we do not want to ignore mouse events coming from a tablet. // See https://msdn.microsoft.com/en-us/library/windows/desktop/ms703320.aspx - const quint64 extraInfo = quint64(GetMessageExtraInfo()); + const auto extraInfo = quint64(GetMessageExtraInfo()); if ((extraInfo & signatureMask) == miWpSignature) { if (extraInfo & 0x80) { // Bit 7 indicates touch event, else tablet pen. source = Qt::MouseEventSynthesizedBySystem; @@ -364,7 +370,7 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd, return true; } - QWindowsWindow *platformWindow = static_cast<QWindowsWindow *>(window->handle()); + auto *platformWindow = static_cast<QWindowsWindow *>(window->handle()); // If the window was recently resized via mouse doubleclick on the frame or title bar, // we don't get WM_LBUTTONDOWN or WM_LBUTTONDBLCLK for the second click, @@ -603,8 +609,8 @@ bool QWindowsMouseHandler::translateTouchEvent(QWindow *window, HWND, QtWindows::WindowsEventType, MSG msg, LRESULT *) { - typedef QWindowSystemInterface::TouchPoint QTouchPoint; - typedef QList<QWindowSystemInterface::TouchPoint> QTouchPointList; + using QTouchPoint = QWindowSystemInterface::TouchPoint; + using QTouchPointList = QList<QWindowSystemInterface::TouchPoint>; if (!QWindowsContext::instance()->initTouch()) { qWarning("Unable to initialize touch handling."); diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.h b/src/plugins/platforms/windows/qwindowsmousehandler.h index 5fe4b09c1e..1d3d1f4761 100644 --- a/src/plugins/platforms/windows/qwindowsmousehandler.h +++ b/src/plugins/platforms/windows/qwindowsmousehandler.h @@ -54,7 +54,7 @@ class QTouchDevice; class QWindowsMouseHandler { - Q_DISABLE_COPY(QWindowsMouseHandler) + Q_DISABLE_COPY_MOVE(QWindowsMouseHandler) public: QWindowsMouseHandler(); @@ -79,7 +79,7 @@ public: static Qt::MouseButtons queryMouseButtons(); QWindow *windowUnderMouse() const { return m_windowUnderMouse.data(); } - void clearWindowUnderMouse() { m_windowUnderMouse = 0; } + void clearWindowUnderMouse() { m_windowUnderMouse = nullptr; } void clearEvents(); private: diff --git a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp index 9003e94c56..d1d181d66e 100644 --- a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp +++ b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp @@ -40,6 +40,7 @@ #include "qwindowsnativeinterface.h" #include "qwindowsclipboard.h" #include "qwindowswindow.h" +#include "qwindowsscreen.h" #include "qwindowscontext.h" #include "qwindowscursor.h" #include "qwindowsopenglcontext.h" @@ -97,7 +98,7 @@ void *QWindowsNativeInterface::nativeResourceForWindow(const QByteArray &resourc qWarning("%s: '%s' requested for null window or window without handle.", __FUNCTION__, resource.constData()); return nullptr; } - QWindowsWindow *bw = static_cast<QWindowsWindow *>(window->handle()); + auto *bw = static_cast<QWindowsWindow *>(window->handle()); int type = resourceType(resource); if (type == HandleType) return bw->handle(); @@ -124,6 +125,21 @@ void *QWindowsNativeInterface::nativeResourceForWindow(const QByteArray &resourc return nullptr; } +void *QWindowsNativeInterface::nativeResourceForScreen(const QByteArray &resource, QScreen *screen) +{ + if (!screen || !screen->handle()) { + qWarning("%s: '%s' requested for null screen or screen without handle.", __FUNCTION__, resource.constData()); + return nullptr; + } + auto *bs = static_cast<QWindowsScreen *>(screen->handle()); + int type = resourceType(resource); + if (type == HandleType) + return bs->handle(); + + qWarning("%s: Invalid key '%s' requested.", __FUNCTION__, resource.constData()); + return nullptr; +} + #ifndef QT_NO_CURSOR void *QWindowsNativeInterface::nativeResourceForCursor(const QByteArray &resource, const QCursor &cursor) { @@ -141,9 +157,9 @@ static const char customMarginPropertyC[] = "WindowsCustomMargins"; QVariant QWindowsNativeInterface::windowProperty(QPlatformWindow *window, const QString &name) const { - QWindowsWindow *platformWindow = static_cast<QWindowsWindow *>(window); + auto *platformWindow = static_cast<QWindowsWindow *>(window); if (name == QLatin1String(customMarginPropertyC)) - return qVariantFromValue(platformWindow->customMargins()); + return QVariant::fromValue(platformWindow->customMargins()); return QVariant(); } @@ -155,7 +171,7 @@ QVariant QWindowsNativeInterface::windowProperty(QPlatformWindow *window, const void QWindowsNativeInterface::setWindowProperty(QPlatformWindow *window, const QString &name, const QVariant &value) { - QWindowsWindow *platformWindow = static_cast<QWindowsWindow *>(window); + auto *platformWindow = static_cast<QWindowsWindow *>(window); if (name == QLatin1String(customMarginPropertyC)) platformWindow->setCustomMargins(qvariant_cast<QMargins>(value)); } @@ -190,7 +206,7 @@ void *QWindowsNativeInterface::nativeResourceForContext(const QByteArray &resour return nullptr; } - QWindowsOpenGLContext *glcontext = static_cast<QWindowsOpenGLContext *>(context->handle()); + auto *glcontext = static_cast<QWindowsOpenGLContext *>(context->handle()); switch (resourceType(resource)) { case RenderingContextType: // Fall through. case EglContextType: diff --git a/src/plugins/platforms/windows/qwindowsnativeinterface.h b/src/plugins/platforms/windows/qwindowsnativeinterface.h index e6f8aae8fb..ce395dc5a4 100644 --- a/src/plugins/platforms/windows/qwindowsnativeinterface.h +++ b/src/plugins/platforms/windows/qwindowsnativeinterface.h @@ -74,6 +74,7 @@ public: void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context) override; #endif void *nativeResourceForWindow(const QByteArray &resource, QWindow *window) override; + void *nativeResourceForScreen(const QByteArray &resource, QScreen *screen) override; #ifndef QT_NO_CURSOR void *nativeResourceForCursor(const QByteArray &resource, const QCursor &cursor) override; #endif diff --git a/src/plugins/platforms/windows/qwindowsole.cpp b/src/plugins/platforms/windows/qwindowsole.cpp index e9c3f2cbf6..f3450e2806 100644 --- a/src/plugins/platforms/windows/qwindowsole.cpp +++ b/src/plugins/platforms/windows/qwindowsole.cpp @@ -110,7 +110,7 @@ QWindowsOleDataObject::GetData(LPFORMATETC pformatetc, LPSTGMEDIUM pmedium) } if (QWindowsContext::verbose > 1 && lcQpaMime().isDebugEnabled()) - qCDebug(lcQpaMime) <<__FUNCTION__ << *pformatetc << "returns" << hex << showbase << quint64(hr); + qCDebug(lcQpaMime) <<__FUNCTION__ << *pformatetc << "returns" << Qt::hex << Qt::showbase << quint64(hr); return hr; } @@ -135,7 +135,7 @@ QWindowsOleDataObject::QueryGetData(LPFORMATETC pformatetc) ResultFromScode(S_OK) : ResultFromScode(S_FALSE); } if (QWindowsContext::verbose > 1) - qCDebug(lcQpaMime) << __FUNCTION__ << " returns 0x" << hex << int(hr); + qCDebug(lcQpaMime) << __FUNCTION__ << " returns 0x" << Qt::hex << int(hr); return hr; } @@ -155,7 +155,7 @@ QWindowsOleDataObject::SetData(LPFORMATETC pFormatetc, STGMEDIUM *pMedium, BOOL HRESULT hr = ResultFromScode(E_NOTIMPL); if (pFormatetc->cfFormat == CF_PERFORMEDDROPEFFECT && pMedium->tymed == TYMED_HGLOBAL) { - DWORD * val = (DWORD*)GlobalLock(pMedium->hGlobal); + auto * val = (DWORD*)GlobalLock(pMedium->hGlobal); performedEffect = *val; GlobalUnlock(pMedium->hGlobal); if (fRelease) @@ -163,7 +163,7 @@ QWindowsOleDataObject::SetData(LPFORMATETC pFormatetc, STGMEDIUM *pMedium, BOOL hr = ResultFromScode(S_OK); } if (QWindowsContext::verbose > 1) - qCDebug(lcQpaMime) << __FUNCTION__ << " returns 0x" << hex << int(hr); + qCDebug(lcQpaMime) << __FUNCTION__ << " returns 0x" << Qt::hex << int(hr); return hr; } @@ -193,7 +193,7 @@ QWindowsOleDataObject::EnumFormatEtc(DWORD dwDirection, LPENUMFORMATETC FAR* ppe fmtetcs.append(formatetc); } - QWindowsOleEnumFmtEtc *enumFmtEtc = new QWindowsOleEnumFmtEtc(fmtetcs); + auto *enumFmtEtc = new QWindowsOleEnumFmtEtc(fmtetcs); *ppenumFormatEtc = enumFmtEtc; if (enumFmtEtc->isNull()) { delete enumFmtEtc; @@ -237,7 +237,7 @@ QWindowsOleEnumFmtEtc::QWindowsOleEnumFmtEtc(const QVector<FORMATETC> &fmtetcs) qCDebug(lcQpaMime) << __FUNCTION__ << fmtetcs; m_lpfmtetcs.reserve(fmtetcs.count()); for (int idx = 0; idx < fmtetcs.count(); ++idx) { - LPFORMATETC destetc = new FORMATETC(); + auto destetc = new FORMATETC(); if (copyFormatEtc(destetc, &(fmtetcs.at(idx)))) { m_lpfmtetcs.append(destetc); } else { @@ -255,7 +255,7 @@ QWindowsOleEnumFmtEtc::QWindowsOleEnumFmtEtc(const QVector<LPFORMATETC> &lpfmtet m_lpfmtetcs.reserve(lpfmtetcs.count()); for (int idx = 0; idx < lpfmtetcs.count(); ++idx) { LPFORMATETC srcetc = lpfmtetcs.at(idx); - LPFORMATETC destetc = new FORMATETC(); + auto destetc = new FORMATETC(); if (copyFormatEtc(destetc, srcetc)) { m_lpfmtetcs.append(destetc); } else { @@ -357,7 +357,7 @@ QWindowsOleEnumFmtEtc::Clone(LPENUMFORMATETC FAR* newEnum) if (newEnum == nullptr) return ResultFromScode(E_INVALIDARG); - QWindowsOleEnumFmtEtc *result = new QWindowsOleEnumFmtEtc(m_lpfmtetcs); + auto *result = new QWindowsOleEnumFmtEtc(m_lpfmtetcs); result->m_nIndex = m_nIndex; if (result->isNull()) { diff --git a/src/plugins/platforms/windows/qwindowsopenglcontext.h b/src/plugins/platforms/windows/qwindowsopenglcontext.h index cc6d93d35e..1416a7e575 100644 --- a/src/plugins/platforms/windows/qwindowsopenglcontext.h +++ b/src/plugins/platforms/windows/qwindowsopenglcontext.h @@ -51,7 +51,7 @@ class QWindowsOpenGLContext; class QWindowsStaticOpenGLContext { - Q_DISABLE_COPY(QWindowsStaticOpenGLContext) + Q_DISABLE_COPY_MOVE(QWindowsStaticOpenGLContext) public: static QWindowsStaticOpenGLContext *create(); virtual ~QWindowsStaticOpenGLContext() = default; @@ -63,7 +63,7 @@ public: // If the windowing system interface needs explicitly created window surfaces (like EGL), // reimplement these. - virtual void *createWindowSurface(void * /*nativeWindow*/, void * /*nativeConfig*/, int * /*err*/) { return 0; } + virtual void *createWindowSurface(void * /*nativeWindow*/, void * /*nativeConfig*/, int * /*err*/) { return nullptr; } virtual void destroyWindowSurface(void * /*nativeSurface*/) { } protected: @@ -75,14 +75,14 @@ private: class QWindowsOpenGLContext : public QPlatformOpenGLContext { - Q_DISABLE_COPY(QWindowsOpenGLContext) + Q_DISABLE_COPY_MOVE(QWindowsOpenGLContext) public: // Returns the native context handle (e.g. HGLRC for WGL, EGLContext for EGL). virtual void *nativeContext() const = 0; // These should be implemented only for some winsys interfaces, for example EGL. // For others, like WGL, they are not relevant. - virtual void *nativeDisplay() const { return 0; } + virtual void *nativeDisplay() const { return nullptr; } virtual void *nativeConfig() const { return 0; } protected: diff --git a/src/plugins/platforms/windows/qwindowsopengltester.cpp b/src/plugins/platforms/windows/qwindowsopengltester.cpp index 840a3a11c4..afc1991e2c 100644 --- a/src/plugins/platforms/windows/qwindowsopengltester.cpp +++ b/src/plugins/platforms/windows/qwindowsopengltester.cpp @@ -83,7 +83,7 @@ static GpuDescription adapterIdentifierToGpuDescription(const D3DADAPTER_IDENTIF class QDirect3D9Handle { public: - Q_DISABLE_COPY(QDirect3D9Handle) + Q_DISABLE_COPY_MOVE(QDirect3D9Handle) QDirect3D9Handle(); ~QDirect3D9Handle(); @@ -188,9 +188,9 @@ QDebug operator<<(QDebug d, const GpuDescription &gd) { QDebugStateSaver s(d); d.nospace(); - d << hex << showbase << "GpuDescription(vendorId=" << gd.vendorId + d << Qt::hex << Qt::showbase << "GpuDescription(vendorId=" << gd.vendorId << ", deviceId=" << gd.deviceId << ", subSysId=" << gd.subSysId - << dec << noshowbase << ", revision=" << gd.revision + << Qt::dec << Qt::noshowbase << ", revision=" << gd.revision << ", driver: " << gd.driverName << ", version=" << gd.driverVersion << ", " << gd.description << gd.gpuSuitableScreen << ')'; @@ -207,11 +207,11 @@ QString GpuDescription::toString() const << "\n Driver Name : " << driverName << "\n Driver Version : " << driverVersion.toString() << "\n Vendor ID : 0x" << qSetPadChar(QLatin1Char('0')) - << uppercasedigits << hex << qSetFieldWidth(4) << vendorId + << Qt::uppercasedigits << Qt::hex << qSetFieldWidth(4) << vendorId << "\n Device ID : 0x" << qSetFieldWidth(4) << deviceId << "\n SubSys ID : 0x" << qSetFieldWidth(8) << subSysId << "\n Revision ID : 0x" << qSetFieldWidth(4) << revision - << dec; + << Qt::dec; if (!gpuSuitableScreen.isEmpty()) str << "\nGL windows forced to screen: " << gpuSuitableScreen; return result; @@ -457,7 +457,7 @@ bool QWindowsOpenGLTester::testDesktopGL() // Check the version. If we got 1.x then it's all hopeless and we can stop right here. typedef const GLubyte * (APIENTRY * GetString_t)(GLenum name); - GetString_t GetString = reinterpret_cast<GetString_t>( + auto GetString = reinterpret_cast<GetString_t>( reinterpret_cast<QFunctionPointer>(::GetProcAddress(lib, "glGetString"))); if (GetString) { if (const char *versionStr = reinterpret_cast<const char *>(GetString(GL_VERSION))) { diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.cpp b/src/plugins/platforms/windows/qwindowspointerhandler.cpp index 71a09304c5..cffd8427a2 100644 --- a/src/plugins/platforms/windows/qwindowspointerhandler.cpp +++ b/src/plugins/platforms/windows/qwindowspointerhandler.cpp @@ -317,10 +317,10 @@ static QTouchDevice *createTouchDevice() return nullptr; const int tabletPc = GetSystemMetrics(SM_TABLETPC); const int maxTouchPoints = GetSystemMetrics(SM_MAXIMUMTOUCHES); - qCDebug(lcQpaEvents) << "Digitizers:" << hex << showbase << (digitizers & ~NID_READY) - << "Ready:" << (digitizers & NID_READY) << dec << noshowbase + qCDebug(lcQpaEvents) << "Digitizers:" << Qt::hex << Qt::showbase << (digitizers & ~NID_READY) + << "Ready:" << (digitizers & NID_READY) << Qt::dec << Qt::noshowbase << "Tablet PC:" << tabletPc << "Max touch points:" << maxTouchPoints; - QTouchDevice *result = new QTouchDevice; + auto *result = new QTouchDevice; result->setType(digitizers & NID_INTEGRATED_TOUCH ? QTouchDevice::TouchScreen : QTouchDevice::TouchPad); QTouchDevice::Capabilities capabilities = QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::NormalizedPosition; @@ -350,7 +350,7 @@ void QWindowsPointerHandler::handleCaptureRelease(QWindow *window, QEvent::Type eventType, Qt::MouseButtons mouseButtons) { - QWindowsWindow *platformWindow = static_cast<QWindowsWindow *>(window->handle()); + auto *platformWindow = static_cast<QWindowsWindow *>(window->handle()); // Qt expects the platform plugin to capture the mouse on any button press until release. if (!platformWindow->hasMouseCapture() && eventType == QEvent::MouseButtonPress) { @@ -386,7 +386,7 @@ void QWindowsPointerHandler::handleEnterLeave(QWindow *window, QWindow *currentWindowUnderPointer, QPoint globalPos) { - QWindowsWindow *platformWindow = static_cast<QWindowsWindow *>(window->handle()); + auto *platformWindow = static_cast<QWindowsWindow *>(window->handle()); const bool hasCapture = platformWindow->hasMouseCapture(); // No enter or leave events are sent as long as there is an autocapturing window. @@ -470,26 +470,26 @@ bool QWindowsPointerHandler::translateTouchEvent(QWindow *window, HWND hwnd, if (!screen) return false; - POINTER_TOUCH_INFO *touchInfo = static_cast<POINTER_TOUCH_INFO *>(vTouchInfo); + auto *touchInfo = static_cast<POINTER_TOUCH_INFO *>(vTouchInfo); const QRect screenGeometry = screen->geometry(); QList<QWindowSystemInterface::TouchPoint> touchPoints; if (QWindowsContext::verbose > 1) - qCDebug(lcQpaEvents).noquote().nospace() << showbase + qCDebug(lcQpaEvents).noquote().nospace() << Qt::showbase << __FUNCTION__ - << " message=" << hex << msg.message - << " count=" << dec << count; + << " message=" << Qt::hex << msg.message + << " count=" << Qt::dec << count; - Qt::TouchPointStates allStates = 0; + Qt::TouchPointStates allStates = nullptr; for (quint32 i = 0; i < count; ++i) { if (QWindowsContext::verbose > 1) - qCDebug(lcQpaEvents).noquote().nospace() << showbase + qCDebug(lcQpaEvents).noquote().nospace() << Qt::showbase << " TouchPoint id=" << touchInfo[i].pointerInfo.pointerId << " frame=" << touchInfo[i].pointerInfo.frameId - << " flags=" << hex << touchInfo[i].pointerInfo.pointerFlags; + << " flags=" << Qt::hex << touchInfo[i].pointerInfo.pointerFlags; QWindowSystemInterface::TouchPoint touchPoint; const quint32 pointerId = touchInfo[i].pointerInfo.pointerId; @@ -550,13 +550,13 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin if (et & QtWindows::NonClientEventFlag) return false; // Let DefWindowProc() handle Non Client messages. - POINTER_PEN_INFO *penInfo = static_cast<POINTER_PEN_INFO *>(vPenInfo); + auto *penInfo = static_cast<POINTER_PEN_INFO *>(vPenInfo); RECT pRect, dRect; if (!QWindowsContext::user32dll.getPointerDeviceRects(penInfo->pointerInfo.sourceDevice, &pRect, &dRect)) return false; - const qint64 sourceDevice = (qint64)penInfo->pointerInfo.sourceDevice; + const auto sourceDevice = (qint64)penInfo->pointerInfo.sourceDevice; const QPoint globalPos = QPoint(penInfo->pointerInfo.ptPixelLocation.x, penInfo->pointerInfo.ptPixelLocation.y); const QPoint localPos = QWindowsGeometryHint::mapFromGlobal(hwnd, globalPos); const QPointF hiResGlobalPos = QPointF(dRect.left + qreal(penInfo->pointerInfo.ptHimetricLocation.x - pRect.left) @@ -571,11 +571,11 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin const int z = 0; if (QWindowsContext::verbose > 1) - qCDebug(lcQpaEvents).noquote().nospace() << showbase + qCDebug(lcQpaEvents).noquote().nospace() << Qt::showbase << __FUNCTION__ << " sourceDevice=" << sourceDevice << " globalPos=" << globalPos << " localPos=" << localPos << " hiResGlobalPos=" << hiResGlobalPos - << " message=" << hex << msg.message - << " flags=" << hex << penInfo->pointerInfo.pointerFlags; + << " message=" << Qt::hex << msg.message + << " flags=" << Qt::hex << penInfo->pointerInfo.pointerFlags; const QTabletEvent::TabletDevice device = QTabletEvent::Stylus; QTabletEvent::PointerType type; @@ -696,7 +696,13 @@ bool QWindowsPointerHandler::translateMouseEvent(QWindow *window, { *result = 0; - const QPoint eventPos(GET_X_LPARAM(msg.lParam), GET_Y_LPARAM(msg.lParam)); + QPoint eventPos(GET_X_LPARAM(msg.lParam), GET_Y_LPARAM(msg.lParam)); + if ((et & QtWindows::NonClientEventFlag) == 0 && QWindowsBaseWindow::isRtlLayout(hwnd)) { + RECT clientArea; + GetClientRect(hwnd, &clientArea); + eventPos.setX(clientArea.right - eventPos.x()); + } + QPoint localPos; QPoint globalPos; diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.h b/src/plugins/platforms/windows/qwindowspointerhandler.h index b6b89cefed..8874db27e3 100644 --- a/src/plugins/platforms/windows/qwindowspointerhandler.h +++ b/src/plugins/platforms/windows/qwindowspointerhandler.h @@ -55,7 +55,7 @@ class QTouchDevice; class QWindowsPointerHandler { - Q_DISABLE_COPY(QWindowsPointerHandler) + Q_DISABLE_COPY_MOVE(QWindowsPointerHandler) public: QWindowsPointerHandler() = default; bool translatePointerEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, LRESULT *result); diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp index cecd06f5a4..df63adf558 100644 --- a/src/plugins/platforms/windows/qwindowsscreen.cpp +++ b/src/plugins/platforms/windows/qwindowsscreen.cpp @@ -73,7 +73,7 @@ static inline QDpi monitorDPI(HMONITOR hMonitor) return {0, 0}; } -typedef QList<QWindowsScreenData> WindowsScreenDataList; +using WindowsScreenDataList = QList<QWindowsScreenData>; static bool monitorData(HMONITOR hMonitor, QWindowsScreenData *data) { @@ -121,7 +121,7 @@ BOOL QT_WIN_CALLBACK monitorEnumCallback(HMONITOR hMonitor, HDC, LPRECT, LPARAM { QWindowsScreenData data; if (monitorData(hMonitor, &data)) { - WindowsScreenDataList *result = reinterpret_cast<WindowsScreenDataList *>(p); + auto *result = reinterpret_cast<WindowsScreenDataList *>(p); // QWindowSystemInterface::handleScreenAdded() documentation specifies that first // added screen will be the primary screen, so order accordingly. // Note that the side effect of this policy is that there is no way to change primary @@ -257,15 +257,6 @@ QWindow *QWindowsScreen::windowAt(const QPoint &screenPoint, unsigned flags) return result; } -qreal QWindowsScreen::pixelDensity() const -{ - // QTBUG-49195: Use logical DPI instead of physical DPI to calculate - // the pixel density since it is reflects the Windows UI scaling. - // High DPI auto scaling should be disabled when the user chooses - // small fonts on a High DPI monitor, resulting in lower logical DPI. - return qMax(1, qRound(logicalDpi().first / 96)); -} - /*! \brief Determine siblings in a virtual desktop system. @@ -329,6 +320,11 @@ void QWindowsScreen::handleChanges(const QWindowsScreenData &newData) } } +HMONITOR QWindowsScreen::handle() const +{ + return m_data.hMonitor; +} + QRect QWindowsScreen::virtualGeometry(const QPlatformScreen *screen) // cf QScreen::virtualGeometry() { QRect result; @@ -556,7 +552,7 @@ bool QWindowsScreenManager::handleScreenChanges() if (existingIndex == 0) primaryScreenChanged = true; } else { - QWindowsScreen *newScreen = new QWindowsScreen(newData); + auto *newScreen = new QWindowsScreen(newData); m_screens.push_back(newScreen); QWindowSystemInterface::handleScreenAdded(newScreen, newData.flags & QWindowsScreenData::PrimaryScreen); diff --git a/src/plugins/platforms/windows/qwindowsscreen.h b/src/plugins/platforms/windows/qwindowsscreen.h index 8ad012512e..2fd56f53cf 100644 --- a/src/plugins/platforms/windows/qwindowsscreen.h +++ b/src/plugins/platforms/windows/qwindowsscreen.h @@ -76,7 +76,7 @@ class QWindowsScreen : public QPlatformScreen { public: #ifndef QT_NO_CURSOR - typedef QScopedPointer<QPlatformCursor> CursorPtr; + using CursorPtr = QScopedPointer<QPlatformCursor>; #endif explicit QWindowsScreen(const QWindowsScreenData &data); @@ -87,7 +87,7 @@ public: QImage::Format format() const override { return m_data.format; } QSizeF physicalSize() const override { return m_data.physicalSizeMM; } QDpi logicalDpi() const override { return m_data.dpi; } - qreal pixelDensity() const override; + QDpi logicalBaseDpi() const override { return QDpi(96, 96); }; qreal devicePixelRatio() const override { return 1.0; } qreal refreshRate() const override { return m_data.refreshRateHz; } QString name() const override { return m_data.name; } @@ -104,6 +104,8 @@ public: inline void handleChanges(const QWindowsScreenData &newData); + HMONITOR handle() const; + #ifndef QT_NO_CURSOR QPlatformCursor *cursor() const override { return m_cursor.data(); } const CursorPtr &cursorPtr() const { return m_cursor; } @@ -125,7 +127,7 @@ private: class QWindowsScreenManager { public: - typedef QList<QWindowsScreen *> WindowsScreenList; + using WindowsScreenList = QList<QWindowsScreen *>; QWindowsScreenManager(); diff --git a/src/plugins/platforms/windows/qwindowsservices.cpp b/src/plugins/platforms/windows/qwindowsservices.cpp index 9504513a5e..83b052bb49 100644 --- a/src/plugins/platforms/windows/qwindowsservices.cpp +++ b/src/plugins/platforms/windows/qwindowsservices.cpp @@ -45,6 +45,8 @@ #include <QtCore/qdebug.h> #include <QtCore/qdir.h> +#include <QtCore/private/qwinregistry_p.h> + #include <shlobj.h> #include <intshcut.h> @@ -57,7 +59,7 @@ static inline bool shellExecute(const QUrl &url) const QString nativeFilePath = url.isLocalFile() && !url.hasFragment() && !url.hasQuery() ? QDir::toNativeSeparators(url.toLocalFile()) : url.toString(QUrl::FullyEncoded); - const quintptr result = + const auto result = reinterpret_cast<quintptr>(ShellExecute(nullptr, nullptr, reinterpret_cast<const wchar_t *>(nativeFilePath.utf16()), nullptr, nullptr, SW_SHOWNORMAL)); @@ -78,35 +80,24 @@ static inline QString mailCommand() const wchar_t mailUserKey[] = L"Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\mailto\\UserChoice"; - wchar_t command[MAX_PATH] = {0}; // Check if user has set preference, otherwise use default. - HKEY handle; - QString keyName; - if (!RegOpenKeyEx(HKEY_CURRENT_USER, mailUserKey, 0, KEY_READ, &handle)) { - DWORD bufferSize = BufferSize; - if (!RegQueryValueEx(handle, L"Progid", nullptr, nullptr, reinterpret_cast<unsigned char*>(command), &bufferSize)) - keyName = QString::fromWCharArray(command); - RegCloseKey(handle); - } + QString keyName = QWinRegistryKey(HKEY_CURRENT_USER, mailUserKey) + .stringValue( L"Progid"); const QLatin1String mailto = keyName.isEmpty() ? QLatin1String("mailto") : QLatin1String(); keyName += mailto + QLatin1String("\\Shell\\Open\\Command"); if (debug) qDebug() << __FUNCTION__ << "keyName=" << keyName; - command[0] = 0; - if (!RegOpenKeyExW(HKEY_CLASSES_ROOT, reinterpret_cast<const wchar_t*>(keyName.utf16()), 0, KEY_READ, &handle)) { - DWORD bufferSize = BufferSize; - RegQueryValueEx(handle, L"", nullptr, nullptr, reinterpret_cast<unsigned char*>(command), &bufferSize); - RegCloseKey(handle); - } + const QString command = QWinRegistryKey(HKEY_CLASSES_ROOT, keyName).stringValue(L""); // QTBUG-57816: As of Windows 10, if there is no mail client installed, an entry like // "rundll32.exe .. url.dll,MailToProtocolHandler %l" is returned. Launching it // silently fails or brings up a broken dialog after a long time, so exclude it and // fall back to ShellExecute() which brings up the URL assocation dialog. - if (!command[0] || wcsstr(command, L",MailToProtocolHandler") != nullptr) + if (command.isEmpty() || command.contains(QLatin1String(",MailToProtocolHandler"))) return QString(); wchar_t expandedCommand[MAX_PATH] = {0}; - return ExpandEnvironmentStrings(command, expandedCommand, MAX_PATH) ? - QString::fromWCharArray(expandedCommand) : QString::fromWCharArray(command); + return ExpandEnvironmentStrings(reinterpret_cast<const wchar_t *>(command.utf16()), + expandedCommand, MAX_PATH) + ? QString::fromWCharArray(expandedCommand) : command; } static inline bool launchMail(const QUrl &url) diff --git a/src/plugins/platforms/windows/qwindowssessionmanager.h b/src/plugins/platforms/windows/qwindowssessionmanager.h index 4c4256f2b0..0769ed1fce 100644 --- a/src/plugins/platforms/windows/qwindowssessionmanager.h +++ b/src/plugins/platforms/windows/qwindowssessionmanager.h @@ -79,7 +79,7 @@ private: bool m_blockUserInput = false; bool m_canceled = false; - Q_DISABLE_COPY(QWindowsSessionManager) + Q_DISABLE_COPY_MOVE(QWindowsSessionManager) }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowssystemtrayicon.cpp b/src/plugins/platforms/windows/qwindowssystemtrayicon.cpp index c0f4e4d014..f2dba4d06b 100644 --- a/src/plugins/platforms/windows/qwindowssystemtrayicon.cpp +++ b/src/plugins/platforms/windows/qwindowssystemtrayicon.cpp @@ -117,7 +117,7 @@ struct QWindowsHwndSystemTrayIconEntry QWindowsSystemTrayIcon *trayIcon; }; -typedef QVector<QWindowsHwndSystemTrayIconEntry> HwndTrayIconEntries; +using HwndTrayIconEntries = QVector<QWindowsHwndSystemTrayIconEntry>; Q_GLOBAL_STATIC(HwndTrayIconEntries, hwndTrayIconEntries) diff --git a/src/plugins/platforms/windows/qwindowstabletsupport.cpp b/src/plugins/platforms/windows/qwindowstabletsupport.cpp index 44b94d044d..cd5a78abb6 100644 --- a/src/plugins/platforms/windows/qwindowstabletsupport.cpp +++ b/src/plugins/platforms/windows/qwindowstabletsupport.cpp @@ -146,13 +146,13 @@ QDebug operator<<(QDebug d, const LOGCONTEXT &lc) QDebugStateSaver saver(d); d.nospace(); d << "LOGCONTEXT(\"" << QString::fromWCharArray(lc.lcName) << "\", options=0x" - << hex << lc.lcOptions << dec; + << Qt::hex << lc.lcOptions << Qt::dec; formatOptions(d, lc.lcOptions); - d << ", status=0x" << hex << lc.lcStatus << ", device=0x" << lc.lcDevice - << dec << ", PktRate=" << lc.lcPktRate + d << ", status=0x" << Qt::hex << lc.lcStatus << ", device=0x" << lc.lcDevice + << Qt::dec << ", PktRate=" << lc.lcPktRate << ", PktData=" << lc.lcPktData << ", PktMode=" << lc.lcPktMode - << ", MoveMask=0x" << hex << lc.lcMoveMask << ", BtnDnMask=0x" << lc.lcBtnDnMask - << ", BtnUpMask=0x" << lc.lcBtnUpMask << dec << ", SysMode=" << lc.lcSysMode + << ", MoveMask=0x" << Qt::hex << lc.lcMoveMask << ", BtnDnMask=0x" << lc.lcBtnDnMask + << ", BtnUpMask=0x" << lc.lcBtnUpMask << Qt::dec << ", SysMode=" << lc.lcSysMode << ", InOrg=(" << lc.lcInOrgX << ", " << lc.lcInOrgY << ", " << lc.lcInOrgZ << "), InExt=(" << lc.lcInExtX << ", " << lc.lcInExtY << ", " << lc.lcInExtZ << ") OutOrg=(" << lc.lcOutOrgX << ", " << lc.lcOutOrgY << ", " @@ -305,7 +305,7 @@ QString QWindowsTabletSupport::description() const << '.' << (specificationVersion & 0xFF) << " implementation: v" << (implementationVersion >> 8) << '.' << (implementationVersion & 0xFF) << ' ' << devices << " device(s), " << cursors << " cursor(s), " - << extensions << " extensions" << ", options: 0x" << hex << opts << dec; + << extensions << " extensions" << ", options: 0x" << Qt::hex << opts << Qt::dec; formatOptions(str, opts); if (m_tiltSupport) str << " tilt"; diff --git a/src/plugins/platforms/windows/qwindowstabletsupport.h b/src/plugins/platforms/windows/qwindowstabletsupport.h index 8f97982308..6bcf3357a5 100644 --- a/src/plugins/platforms/windows/qwindowstabletsupport.h +++ b/src/plugins/platforms/windows/qwindowstabletsupport.h @@ -110,7 +110,7 @@ QDebug operator<<(QDebug d, const QWindowsTabletDeviceData &t); class QWindowsTabletSupport { - Q_DISABLE_COPY(QWindowsTabletSupport) + Q_DISABLE_COPY_MOVE(QWindowsTabletSupport) explicit QWindowsTabletSupport(HWND window, HCTX context); diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp index a6b9781252..40f9652cbd 100644 --- a/src/plugins/platforms/windows/qwindowstheme.cpp +++ b/src/plugins/platforms/windows/qwindowstheme.cpp @@ -162,25 +162,19 @@ public: m_init = CoInitializeEx(nullptr, COINIT_MULTITHREADED); QMutexLocker readyLocker(&m_readyMutex); - while (!m_cancelled.load()) { - if (!m_params && !m_cancelled.load() + while (!m_cancelled.loadRelaxed()) { + if (!m_params && !m_cancelled.loadRelaxed() && !m_readyCondition.wait(&m_readyMutex, 1000)) continue; if (m_params) { const QString fileName = m_params->fileName; SHFILEINFO info; -#ifndef Q_OS_WINCE - const UINT oldErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX); -#endif const bool result = SHGetFileInfo(reinterpret_cast<const wchar_t *>(fileName.utf16()), m_params->attributes, &info, sizeof(SHFILEINFO), m_params->flags); -#ifndef Q_OS_WINCE - SetErrorMode(oldErrorMode); -#endif m_doneMutex.lock(); - if (!m_cancelled.load()) { + if (!m_cancelled.loadRelaxed()) { *m_params->result = result; memcpy(m_params->info, &info, sizeof(SHFILEINFO)); } @@ -210,7 +204,7 @@ public: void cancel() { QMutexLocker doneLocker(&m_doneMutex); - m_cancelled.store(1); + m_cancelled.storeRelaxed(1); m_readyCondition.wakeAll(); } @@ -472,6 +466,8 @@ QVariant QWindowsTheme::themeHint(ThemeHint hint) const result = int(scrollLines); return QVariant(result); } + case MouseDoubleClickDistance: + return GetSystemMetrics(SM_CXDOUBLECLK); default: break; } @@ -589,7 +585,7 @@ Q_GUI_EXPORT QPixmap qt_pixmapFromWinHICON(HICON icon); static QPixmap loadIconFromShell32(int resourceId, QSizeF size) { if (const HMODULE hmod = QSystemLibrary::load(L"shell32")) { - HICON iconHandle = + auto iconHandle = static_cast<HICON>(LoadImage(hmod, MAKEINTRESOURCE(resourceId), IMAGE_ICON, int(size.width()), int(size.height()), 0)); if (iconHandle) { diff --git a/src/plugins/platforms/windows/qwindowstheme.h b/src/plugins/platforms/windows/qwindowstheme.h index 28c69e4ec1..07120230ce 100644 --- a/src/plugins/platforms/windows/qwindowstheme.h +++ b/src/plugins/platforms/windows/qwindowstheme.h @@ -51,7 +51,7 @@ class QWindow; class QWindowsTheme : public QPlatformTheme { - Q_DISABLE_COPY(QWindowsTheme) + Q_DISABLE_COPY_MOVE(QWindowsTheme) public: QWindowsTheme(); ~QWindowsTheme() override; @@ -71,7 +71,7 @@ public: QPixmap standardPixmap(StandardPixmap sp, const QSizeF &size) const override; - QIcon fileIcon(const QFileInfo &fileInfo, QPlatformTheme::IconOptions iconOptions = 0) const override; + QIcon fileIcon(const QFileInfo &fileInfo, QPlatformTheme::IconOptions iconOptions = nullptr) const override; void windowsThemeChanged(QWindow *window); void displayChanged() { refreshIconPixmapSizes(); } diff --git a/src/plugins/platforms/windows/qwindowsthreadpoolrunner.h b/src/plugins/platforms/windows/qwindowsthreadpoolrunner.h index 731e4b5432..ffe2e62069 100644 --- a/src/plugins/platforms/windows/qwindowsthreadpoolrunner.h +++ b/src/plugins/platforms/windows/qwindowsthreadpoolrunner.h @@ -59,7 +59,7 @@ QT_BEGIN_NAMESPACE */ class QWindowsThreadPoolRunner { - Q_DISABLE_COPY(QWindowsThreadPoolRunner) + Q_DISABLE_COPY_MOVE(QWindowsThreadPoolRunner) #if QT_CONFIG(thread) template <class RunnableFunction> // nested class implementing QRunnable to execute a function. diff --git a/src/plugins/platforms/windows/qwindowsvulkaninstance.cpp b/src/plugins/platforms/windows/qwindowsvulkaninstance.cpp index 7a01483abd..812ea8193a 100644 --- a/src/plugins/platforms/windows/qwindowsvulkaninstance.cpp +++ b/src/plugins/platforms/windows/qwindowsvulkaninstance.cpp @@ -81,7 +81,7 @@ bool QWindowsVulkanInstance::supportsPresent(VkPhysicalDevice physicalDevice, VkSurfaceKHR QWindowsVulkanInstance::createSurface(HWND win) { - VkSurfaceKHR surface = 0; + VkSurfaceKHR surface = VK_NULL_HANDLE; if (!m_createSurface) { m_createSurface = reinterpret_cast<PFN_vkCreateWin32SurfaceKHR>( diff --git a/src/plugins/platforms/windows/qwindowsvulkaninstance.h b/src/plugins/platforms/windows/qwindowsvulkaninstance.h index 3292137c39..cc7ef476d4 100644 --- a/src/plugins/platforms/windows/qwindowsvulkaninstance.h +++ b/src/plugins/platforms/windows/qwindowsvulkaninstance.h @@ -53,7 +53,7 @@ QT_BEGIN_NAMESPACE class QWindowsVulkanInstance : public QBasicPlatformVulkanInstance { - Q_DISABLE_COPY(QWindowsVulkanInstance) + Q_DISABLE_COPY_MOVE(QWindowsVulkanInstance) public: QWindowsVulkanInstance(QVulkanInstance *instance); diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 1d8b252029..a4f4099aa6 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -86,7 +86,7 @@ QT_BEGIN_NAMESPACE -typedef QSharedPointer<QWindowCreationContext> QWindowCreationContextPtr; +using QWindowCreationContextPtr = QSharedPointer<QWindowCreationContext>; enum { defaultWindowWidth = 160, @@ -134,6 +134,10 @@ static QByteArray debugWinExStyle(DWORD exStyle) rc += " WS_EX_LAYERED"; if (exStyle & WS_EX_DLGMODALFRAME) rc += " WS_EX_DLGMODALFRAME"; + if (exStyle & WS_EX_LAYOUTRTL) + rc += " WS_EX_LAYOUTRTL"; + if (exStyle & WS_EX_NOINHERITLAYOUT) + rc += " WS_EX_NOINHERITLAYOUT"; return rc; } @@ -239,7 +243,7 @@ QDebug operator<<(QDebug d, const WINDOWPLACEMENT &wp) QDebugStateSaver saver(d); d.nospace(); d.noquote(); - d << "WINDOWPLACEMENT(flags=0x" << hex << wp.flags << dec << ", showCmd=" + d << "WINDOWPLACEMENT(flags=0x" << Qt::hex << wp.flags << Qt::dec << ", showCmd=" << wp.showCmd << ", ptMinPosition=" << wp.ptMinPosition << ", ptMaxPosition=" << wp.ptMaxPosition << ", rcNormalPosition=" << wp.rcNormalPosition; return d; @@ -249,7 +253,7 @@ QDebug operator<<(QDebug d, const GUID &guid) { QDebugStateSaver saver(d); d.nospace(); - d << '{' << hex << uppercasedigits << qSetPadChar(QLatin1Char('0')) + d << '{' << Qt::hex << Qt::uppercasedigits << qSetPadChar(QLatin1Char('0')) << qSetFieldWidth(8) << guid.Data1 << qSetFieldWidth(0) << '-' << qSetFieldWidth(4) << guid.Data2 << qSetFieldWidth(0) << '-' << qSetFieldWidth(4) @@ -307,7 +311,7 @@ static inline QRect frameGeometry(HWND hwnd, bool topLevel) const int width = rect.right - rect.left; const int height = rect.bottom - rect.top; POINT leftTop = { rect.left, rect.top }; - ScreenToClient(parent, &leftTop); + screenToClient(parent, &leftTop); rect.left = leftTop.x; rect.top = leftTop.y; rect.right = leftTop.x + width; @@ -490,7 +494,7 @@ static QMargins invisibleMargins(QPoint screenPoint) struct WindowCreationData { - typedef QWindowsWindowData WindowData; + using WindowData = QWindowsWindowData; enum Flags { ForceChild = 0x1, ForceTopLevel = 0x2 }; void fromWindow(const QWindow *w, const Qt::WindowFlags flags, unsigned creationFlags = 0); @@ -667,6 +671,17 @@ void WindowCreationData::fromWindow(const QWindow *w, const Qt::WindowFlags flag if ((flags & Qt::MSWindowsFixedSizeDialogHint)) dialog = true; + // This causes the title bar to drawn RTL and the close button + // to be left. Note that this causes: + // - All DCs created on the Window to have RTL layout (see SetLayout) + // - ClientToScreen() and ScreenToClient() to work in reverse as well. + // - Mouse event coordinates to be mirrored. + // - Positioning of child Windows. + if (QGuiApplication::layoutDirection() == Qt::RightToLeft + && (QWindowsIntegration::instance()->options() & QWindowsIntegration::RtlEnabled) != 0) { + exStyle |= WS_EX_LAYOUTRTL | WS_EX_NOINHERITLAYOUT; + } + // Parent: Use transient parent for top levels. if (popup) { flags |= Qt::WindowStaysOnTopHint; // a popup stays on top, no parent. @@ -749,8 +764,8 @@ QWindowsWindowData if (title.isEmpty() && (result.flags & Qt::WindowTitleHint)) title = topLevel ? qAppName() : w->objectName(); - const wchar_t *titleUtf16 = reinterpret_cast<const wchar_t *>(title.utf16()); - const wchar_t *classNameUtf16 = reinterpret_cast<const wchar_t *>(windowClassName.utf16()); + const auto *titleUtf16 = reinterpret_cast<const wchar_t *>(title.utf16()); + const auto *classNameUtf16 = reinterpret_cast<const wchar_t *>(windowClassName.utf16()); // Capture events before CreateWindowEx() returns. The context is cleared in // the QWindowsWindow constructor. @@ -772,6 +787,16 @@ QWindowsWindowData QPoint pos = calcPosition(w, context, invMargins); + // Mirror the position when creating on a parent in RTL mode, ditto for the obtained geometry. + int mirrorParentWidth = 0; + if (!w->isTopLevel() && QWindowsBaseWindow::isRtlLayout(parentHandle)) { + RECT rect; + GetClientRect(parentHandle, &rect); + mirrorParentWidth = rect.right; + } + if (mirrorParentWidth != 0 && pos.x() != CW_USEDEFAULT && context->frameWidth != CW_USEDEFAULT) + pos.setX(mirrorParentWidth - context->frameWidth - pos.x()); + result.hwnd = CreateWindowEx(exStyle, classNameUtf16, titleUtf16, style, pos.x(), pos.y(), @@ -779,14 +804,21 @@ QWindowsWindowData parentHandle, nullptr, appinst, nullptr); qCDebug(lcQpaWindows).nospace() << "CreateWindowEx: returns " << w << ' ' << result.hwnd << " obtained geometry: " - << context->obtainedGeometry << ' ' << context->margins; + << context->obtainedPos << context->obtainedSize << ' ' << context->margins; if (!result.hwnd) { qErrnoWarning("%s: CreateWindowEx failed", __FUNCTION__); return result; } - result.geometry = context->obtainedGeometry; + if (mirrorParentWidth != 0) { + context->obtainedPos.setX(mirrorParentWidth - context->obtainedSize.width() + - context->obtainedPos.x()); + } + + QRect obtainedGeometry(context->obtainedPos, context->obtainedSize); + + result.geometry = obtainedGeometry; result.fullFrameMargins = context->margins; result.embedded = embedded; result.hasFrame = hasFrame; @@ -905,7 +937,7 @@ QMargins QWindowsGeometryHint::frame(DWORD style, DWORD exStyle, qreal dpi) const QMargins result(qAbs(rect.left), qAbs(rect.top), qAbs(rect.right), qAbs(rect.bottom)); qCDebug(lcQpaWindows).nospace() << __FUNCTION__ << " style=" - << showbase << hex << style << " exStyle=" << exStyle << dec << noshowbase + << Qt::showbase << Qt::hex << style << " exStyle=" << exStyle << Qt::dec << Qt::noshowbase << " dpi=" << dpi << ' ' << rect << ' ' << result; return result; @@ -950,7 +982,7 @@ bool QWindowsGeometryHint::handleCalculateSize(const QMargins &customMargins, co if (!msg.wParam || customMargins.isNull()) return false; *result = DefWindowProc(msg.hwnd, msg.message, msg.wParam, msg.lParam); - NCCALCSIZE_PARAMS *ncp = reinterpret_cast<NCCALCSIZE_PARAMS *>(msg.lParam); + auto *ncp = reinterpret_cast<NCCALCSIZE_PARAMS *>(msg.lParam); const RECT oldClientArea = ncp->rgrc[0]; ncp->rgrc[0].left += customMargins.left(); ncp->rgrc[0].top += customMargins.top(); @@ -1033,6 +1065,11 @@ bool QWindowsGeometryHint::positionIncludesFrame(const QWindow *w) \ingroup qt-lighthouse-win */ +bool QWindowsBaseWindow::isRtlLayout(HWND hwnd) +{ + return (GetWindowLongPtrW(hwnd, GWL_EXSTYLE) & WS_EX_LAYOUTRTL) != 0; +} + QWindowsBaseWindow *QWindowsBaseWindow::baseWindowOf(const QWindow *w) { if (w) { @@ -1195,7 +1232,9 @@ QWindowCreationContext::QWindowCreationContext(const QWindow *w, DWORD style, DWORD exStyle) : window(w), requestedGeometryIn(geometryIn), - requestedGeometry(geometry), obtainedGeometry(geometry), + requestedGeometry(geometry), + obtainedPos(geometryIn.topLeft()), + obtainedSize(geometryIn.size()), margins(QWindowsGeometryHint::frame(w, geometry, style, exStyle)), customMargins(cm) { @@ -1266,7 +1305,7 @@ QWindowsWindow::QWindowsWindow(QWindow *aWindow, const QWindowsWindowData &data) m_cursor(new CursorHandle), m_format(aWindow->requestedFormat()) #if QT_CONFIG(vulkan) - , m_vkSurface(0) + , m_vkSurface(VK_NULL_HANDLE) #endif { QWindowsContext::instance()->addWindow(m_data.hwnd, this); @@ -1323,11 +1362,12 @@ void QWindowsWindow::initialize() // will send the message) and screen change signals of QWindow. if (w->type() != Qt::Desktop) { const Qt::WindowState state = w->windowState(); + const QRect obtainedGeometry(creationContext->obtainedPos, creationContext->obtainedSize); if (state != Qt::WindowMaximized && state != Qt::WindowFullScreen - && creationContext->requestedGeometryIn != creationContext->obtainedGeometry) { - QWindowSystemInterface::handleGeometryChange<QWindowSystemInterface::SynchronousDelivery>(w, creationContext->obtainedGeometry); + && creationContext->requestedGeometryIn != obtainedGeometry) { + QWindowSystemInterface::handleGeometryChange<QWindowSystemInterface::SynchronousDelivery>(w, obtainedGeometry); } - QPlatformScreen *obtainedScreen = screenForGeometry(creationContext->obtainedGeometry); + QPlatformScreen *obtainedScreen = screenForGeometry(obtainedGeometry); if (obtainedScreen && screen() != obtainedScreen) QWindowSystemInterface::handleWindowScreenChanged<QWindowSystemInterface::SynchronousDelivery>(w, obtainedScreen->screen()); } @@ -1366,14 +1406,14 @@ void QWindowsWindow::destroyWindow() QVulkanInstance *inst = window()->vulkanInstance(); if (inst) static_cast<QWindowsVulkanInstance *>(inst->handle())->destroySurface(m_vkSurface); - m_vkSurface = 0; + m_vkSurface = VK_NULL_HANDLE; } #endif #ifndef QT_NO_OPENGL if (m_surface) { if (QWindowsStaticOpenGLContext *staticOpenGLContext = QWindowsIntegration::staticOpenGLContext()) staticOpenGLContext->destroyWindowSurface(m_surface); - m_surface = 0; + m_surface = nullptr; } #endif DestroyWindow(m_data.hwnd); @@ -1462,7 +1502,7 @@ QWindow *QWindowsWindow::topLevelOf(QWindow *w) w = parent; if (const QPlatformWindow *handle = w->handle()) { - const QWindowsWindow *ww = static_cast<const QWindowsWindow *>(handle); + const auto *ww = static_cast<const QWindowsWindow *>(handle); if (ww->isEmbedded()) { HWND parentHWND = GetAncestor(ww->handle(), GA_PARENT); const HWND desktopHwnd = GetDesktopWindow(); @@ -1536,7 +1576,7 @@ bool QWindowsWindow::isActive() const bool QWindowsWindow::isAncestorOf(const QPlatformWindow *child) const { - const QWindowsWindow *childWindow = static_cast<const QWindowsWindow *>(child); + const auto *childWindow = static_cast<const QWindowsWindow *>(child); return IsChild(m_data.hwnd, childWindow->handle()); } @@ -1685,7 +1725,7 @@ void QWindowsWindow::setParent_sys(const QPlatformWindow *parent) HWND oldParentHWND = parentHwnd(); HWND newParentHWND = nullptr; if (parent) { - const QWindowsWindow *parentW = static_cast<const QWindowsWindow *>(parent); + const auto *parentW = static_cast<const QWindowsWindow *>(parent); newParentHWND = parentW->handle(); } @@ -1946,7 +1986,16 @@ void QWindowsBaseWindow::setGeometry_sys(const QRect &rect) const windowPlacement.showCmd = windowPlacement.showCmd == SW_SHOWMINIMIZED ? SW_SHOWMINIMIZED : SW_HIDE; result = SetWindowPlacement(hwnd, &windowPlacement); } else { - result = MoveWindow(hwnd, frameGeometry.x(), frameGeometry.y(), + int x = frameGeometry.x(); + if (!window()->isTopLevel()) { + const HWND parentHandle = GetParent(hwnd); + if (isRtlLayout(parentHandle)) { + RECT rect; + GetClientRect(parentHandle, &rect); + x = rect.right - frameGeometry.width() - x; + } + } + result = MoveWindow(hwnd, x, frameGeometry.y(), frameGeometry.width(), frameGeometry.height(), true); } qCDebug(lcQpaWindows) << '<' << __FUNCTION__ << window() @@ -1962,8 +2011,11 @@ void QWindowsBaseWindow::setGeometry_sys(const QRect &rect) const HDC QWindowsWindow::getDC() { - if (!m_hdc) + if (!m_hdc) { m_hdc = GetDC(handle()); + if (QGuiApplication::layoutDirection() == Qt::RightToLeft) + SetLayout(m_hdc, 0); // Clear RTL layout + } return m_hdc; } @@ -2318,7 +2370,7 @@ void QWindowsWindow::propagateSizeHints() bool QWindowsWindow::handleGeometryChangingMessage(MSG *message, const QWindow *qWindow, const QMargins &margins) { - WINDOWPOS *windowPos = reinterpret_cast<WINDOWPOS *>(message->lParam); + auto *windowPos = reinterpret_cast<WINDOWPOS *>(message->lParam); if ((windowPos->flags & SWP_NOZORDER) == 0) { if (QWindowsWindow *platformWindow = QWindowsWindow::windowsWindowOf(qWindow)) { QWindow *parentWindow = qWindow->parent(); @@ -2900,14 +2952,14 @@ void QWindowsWindow::invalidateSurface() QVulkanInstance *inst = window()->vulkanInstance(); if (inst) static_cast<QWindowsVulkanInstance *>(inst->handle())->destroySurface(m_vkSurface); - m_vkSurface = 0; + m_vkSurface = VK_NULL_HANDLE; } #endif #ifndef QT_NO_OPENGL if (m_surface) { if (QWindowsStaticOpenGLContext *staticOpenGLContext = QWindowsIntegration::staticOpenGLContext()) staticOpenGLContext->destroyWindowSurface(m_surface); - m_surface = 0; + m_surface = nullptr; } #endif // QT_NO_OPENGL } diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h index 958564aa86..7efbcf900c 100644 --- a/src/plugins/platforms/windows/qwindowswindow.h +++ b/src/plugins/platforms/windows/qwindowswindow.h @@ -89,7 +89,8 @@ struct QWindowCreationContext const QWindow *window; QRect requestedGeometryIn; // QWindow scaled QRect requestedGeometry; // after QPlatformWindow::initialGeometry() - QRect obtainedGeometry; + QPoint obtainedPos; + QSize obtainedSize; QMargins margins; QMargins customMargins; // User-defined, additional frame for WM_NCCALCSIZE int frameX = CW_USEDEFAULT; // Passed on to CreateWindowEx(), including frame. @@ -105,7 +106,7 @@ struct QWindowsWindowData QRect geometry; QMargins fullFrameMargins; // Do not use directly for windows, see FrameDirty. QMargins customMargins; // User-defined, additional frame for NCCALCSIZE - HWND hwnd = 0; + HWND hwnd = nullptr; bool embedded = false; bool hasFrame = false; @@ -116,7 +117,7 @@ struct QWindowsWindowData class QWindowsBaseWindow : public QPlatformWindow { - Q_DISABLE_COPY(QWindowsBaseWindow) + Q_DISABLE_COPY_MOVE(QWindowsBaseWindow) public: explicit QWindowsBaseWindow(QWindow *window) : QPlatformWindow(window) {} @@ -134,6 +135,7 @@ public: unsigned style() const { return GetWindowLongPtr(handle(), GWL_STYLE); } unsigned exStyle() const { return GetWindowLongPtr(handle(), GWL_EXSTYLE); } + static bool isRtlLayout(HWND hwnd); static QWindowsBaseWindow *baseWindowOf(const QWindow *w); static HWND handleOf(const QWindow *w); @@ -355,7 +357,7 @@ private: inline void setParent_sys(const QPlatformWindow *parent); inline void updateTransientParent() const; void destroyWindow(); - inline bool isDropSiteEnabled() const { return m_dropTarget != 0; } + inline bool isDropSiteEnabled() const { return m_dropTarget != nullptr; } void setDropSiteEnabled(bool enabled); void updateDropSite(bool topLevel); void handleGeometryChange(); @@ -366,7 +368,7 @@ private: mutable QWindowsWindowData m_data; QPointer<QWindowsMenuBar> m_menuBar; mutable unsigned m_flags = WithinCreate; - HDC m_hdc = 0; + HDC m_hdc = nullptr; Qt::WindowStates m_windowState = Qt::WindowNoState; qreal m_opacity = 1; #ifndef QT_NO_CURSOR @@ -376,15 +378,15 @@ private: unsigned m_savedStyle = 0; QRect m_savedFrameGeometry; const QSurfaceFormat m_format; - HICON m_iconSmall = 0; - HICON m_iconBig = 0; + HICON m_iconSmall = nullptr; + HICON m_iconBig = nullptr; void *m_surface = nullptr; static bool m_screenForGLInitialized; #if QT_CONFIG(vulkan) // note: intentionally not using void * in order to avoid breaking x86 - VkSurfaceKHR m_vkSurface = 0; + VkSurfaceKHR m_vkSurface = VK_NULL_HANDLE; #endif static bool m_borderInFullScreenDefault; }; @@ -399,18 +401,38 @@ QDebug operator<<(QDebug d, const WINDOWPOS &); QDebug operator<<(QDebug d, const GUID &guid); #endif // !QT_NO_DEBUG_STREAM +static inline void clientToScreen(HWND hwnd, POINT *wP) +{ + if (QWindowsBaseWindow::isRtlLayout(hwnd)) { + RECT clientArea; + GetClientRect(hwnd, &clientArea); + wP->x = clientArea.right - wP->x; + } + ClientToScreen(hwnd, wP); +} + +static inline void screenToClient(HWND hwnd, POINT *wP) +{ + ScreenToClient(hwnd, wP); + if (QWindowsBaseWindow::isRtlLayout(hwnd)) { + RECT clientArea; + GetClientRect(hwnd, &clientArea); + wP->x = clientArea.right - wP->x; + } +} + // ---------- QWindowsGeometryHint inline functions. QPoint QWindowsGeometryHint::mapToGlobal(HWND hwnd, const QPoint &qp) { POINT p = { qp.x(), qp.y() }; - ClientToScreen(hwnd, &p); + clientToScreen(hwnd, &p); return QPoint(p.x, p.y); } QPoint QWindowsGeometryHint::mapFromGlobal(const HWND hwnd, const QPoint &qp) { POINT p = { qp.x(), qp.y() }; - ScreenToClient(hwnd, &p); + screenToClient(hwnd, &p); return QPoint(p.x, p.y); } @@ -449,11 +471,11 @@ inline void QWindowsWindow::destroyIcon() { if (m_iconBig) { DestroyIcon(m_iconBig); - m_iconBig = 0; + m_iconBig = nullptr; } if (m_iconSmall) { DestroyIcon(m_iconSmall); - m_iconSmall = 0; + m_iconSmall = nullptr; } } diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiabaseprovider.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiabaseprovider.h index 9caa7d6898..a20df28e3f 100644 --- a/src/plugins/platforms/windows/uiautomation/qwindowsuiabaseprovider.h +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiabaseprovider.h @@ -57,7 +57,7 @@ class QAccessibleInterface; class QWindowsUiaBaseProvider : public QObject { Q_OBJECT - Q_DISABLE_COPY(QWindowsUiaBaseProvider) + Q_DISABLE_COPY_MOVE(QWindowsUiaBaseProvider) public: explicit QWindowsUiaBaseProvider(QAccessible::Id id); virtual ~QWindowsUiaBaseProvider(); diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiagriditemprovider.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiagriditemprovider.h index 3d17056d38..3244122038 100644 --- a/src/plugins/platforms/windows/uiautomation/qwindowsuiagriditemprovider.h +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiagriditemprovider.h @@ -51,7 +51,7 @@ QT_BEGIN_NAMESPACE class QWindowsUiaGridItemProvider : public QWindowsUiaBaseProvider, public QWindowsComBase<IGridItemProvider> { - Q_DISABLE_COPY(QWindowsUiaGridItemProvider) + Q_DISABLE_COPY_MOVE(QWindowsUiaGridItemProvider) public: explicit QWindowsUiaGridItemProvider(QAccessible::Id id); virtual ~QWindowsUiaGridItemProvider(); diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiagridprovider.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiagridprovider.h index b96fc1a93c..0e5f81108e 100644 --- a/src/plugins/platforms/windows/uiautomation/qwindowsuiagridprovider.h +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiagridprovider.h @@ -51,7 +51,7 @@ QT_BEGIN_NAMESPACE class QWindowsUiaGridProvider : public QWindowsUiaBaseProvider, public QWindowsComBase<IGridProvider> { - Q_DISABLE_COPY(QWindowsUiaGridProvider) + Q_DISABLE_COPY_MOVE(QWindowsUiaGridProvider) public: explicit QWindowsUiaGridProvider(QAccessible::Id id); virtual ~QWindowsUiaGridProvider(); diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiainvokeprovider.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiainvokeprovider.h index 5fb509c5f3..7d646894a1 100644 --- a/src/plugins/platforms/windows/uiautomation/qwindowsuiainvokeprovider.h +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiainvokeprovider.h @@ -51,7 +51,7 @@ QT_BEGIN_NAMESPACE class QWindowsUiaInvokeProvider : public QWindowsUiaBaseProvider, public QWindowsComBase<IInvokeProvider> { - Q_DISABLE_COPY(QWindowsUiaInvokeProvider) + Q_DISABLE_COPY_MOVE(QWindowsUiaInvokeProvider) public: explicit QWindowsUiaInvokeProvider(QAccessible::Id id); virtual ~QWindowsUiaInvokeProvider(); diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp index 5a05adbf81..b2b401dd40 100644 --- a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp @@ -82,7 +82,7 @@ QWindowsUiaMainProvider *QWindowsUiaMainProvider::providerForAccessible(QAccessi QAccessible::Id id = QAccessible::uniqueId(accessible); QWindowsUiaProviderCache *providerCache = QWindowsUiaProviderCache::instance(); - QWindowsUiaMainProvider *provider = qobject_cast<QWindowsUiaMainProvider *>(providerCache->providerForId(id)); + auto *provider = qobject_cast<QWindowsUiaMainProvider *>(providerCache->providerForId(id)); if (provider) { provider->AddRef(); @@ -153,7 +153,7 @@ void QWindowsUiaMainProvider::notifyValueChange(QAccessibleValueChangeEvent *eve int count = listacc->childCount(); for (int i = 0; i < count; ++i) { QAccessibleInterface *item = listacc->child(i); - if (item && item->text(QAccessible::Name) == event->value()) { + if (item && item->isValid() && item->text(QAccessible::Name) == event->value()) { if (!item->state().selected) { if (QAccessibleActionInterface *actionInterface = item->actionInterface()) actionInterface->doAction(QAccessibleActionInterface::toggleAction()); diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.h index df0d60f9c9..cdc239ed99 100644 --- a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.h +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.h @@ -60,7 +60,7 @@ class QWindowsUiaMainProvider : public IRawElementProviderFragmentRoot { Q_OBJECT - Q_DISABLE_COPY(QWindowsUiaMainProvider) + Q_DISABLE_COPY_MOVE(QWindowsUiaMainProvider) public: static QWindowsUiaMainProvider *providerForAccessible(QAccessibleInterface *accessible); explicit QWindowsUiaMainProvider(QAccessibleInterface *a, int initialRefCount = 1); diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiarangevalueprovider.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiarangevalueprovider.h index c5e0a03ee5..fc82d3a2cc 100644 --- a/src/plugins/platforms/windows/uiautomation/qwindowsuiarangevalueprovider.h +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiarangevalueprovider.h @@ -51,7 +51,7 @@ QT_BEGIN_NAMESPACE class QWindowsUiaRangeValueProvider : public QWindowsUiaBaseProvider, public QWindowsComBase<IRangeValueProvider> { - Q_DISABLE_COPY(QWindowsUiaRangeValueProvider) + Q_DISABLE_COPY_MOVE(QWindowsUiaRangeValueProvider) public: explicit QWindowsUiaRangeValueProvider(QAccessible::Id id); virtual ~QWindowsUiaRangeValueProvider(); diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionitemprovider.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionitemprovider.h index 1f2605188b..4b59c4e40f 100644 --- a/src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionitemprovider.h +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionitemprovider.h @@ -51,7 +51,7 @@ QT_BEGIN_NAMESPACE class QWindowsUiaSelectionItemProvider : public QWindowsUiaBaseProvider, public QWindowsComBase<ISelectionItemProvider> { - Q_DISABLE_COPY(QWindowsUiaSelectionItemProvider) + Q_DISABLE_COPY_MOVE(QWindowsUiaSelectionItemProvider) public: explicit QWindowsUiaSelectionItemProvider(QAccessible::Id id); virtual ~QWindowsUiaSelectionItemProvider(); diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionprovider.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionprovider.h index 0376d25804..ee1044ec7a 100644 --- a/src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionprovider.h +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionprovider.h @@ -51,7 +51,7 @@ QT_BEGIN_NAMESPACE class QWindowsUiaSelectionProvider : public QWindowsUiaBaseProvider, public QWindowsComBase<ISelectionProvider> { - Q_DISABLE_COPY(QWindowsUiaSelectionProvider) + Q_DISABLE_COPY_MOVE(QWindowsUiaSelectionProvider) public: explicit QWindowsUiaSelectionProvider(QAccessible::Id id); virtual ~QWindowsUiaSelectionProvider(); diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiatableitemprovider.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiatableitemprovider.h index bf4b52ee0b..9804c35f8e 100644 --- a/src/plugins/platforms/windows/uiautomation/qwindowsuiatableitemprovider.h +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiatableitemprovider.h @@ -51,7 +51,7 @@ QT_BEGIN_NAMESPACE class QWindowsUiaTableItemProvider : public QWindowsUiaBaseProvider, public QWindowsComBase<ITableItemProvider> { - Q_DISABLE_COPY(QWindowsUiaTableItemProvider) + Q_DISABLE_COPY_MOVE(QWindowsUiaTableItemProvider) public: explicit QWindowsUiaTableItemProvider(QAccessible::Id id); virtual ~QWindowsUiaTableItemProvider(); diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiatableprovider.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiatableprovider.h index 94c8ab93a7..a8b16035ec 100644 --- a/src/plugins/platforms/windows/uiautomation/qwindowsuiatableprovider.h +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiatableprovider.h @@ -51,7 +51,7 @@ QT_BEGIN_NAMESPACE class QWindowsUiaTableProvider : public QWindowsUiaBaseProvider, public QWindowsComBase<ITableProvider> { - Q_DISABLE_COPY(QWindowsUiaTableProvider) + Q_DISABLE_COPY_MOVE(QWindowsUiaTableProvider) public: explicit QWindowsUiaTableProvider(QAccessible::Id id); virtual ~QWindowsUiaTableProvider(); diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiatextprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiatextprovider.cpp index 9d1e72fb78..50ecfc7ecd 100644 --- a/src/plugins/platforms/windows/uiautomation/qwindowsuiatextprovider.cpp +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiatextprovider.cpp @@ -100,7 +100,7 @@ HRESULT STDMETHODCALLTYPE QWindowsUiaTextProvider::GetSelection(SAFEARRAY **pRet for (LONG i = 0; i < selCount; ++i) { int startOffset = 0, endOffset = 0; textInterface->selection((int)i, &startOffset, &endOffset); - QWindowsUiaTextRangeProvider *textRangeProvider = new QWindowsUiaTextRangeProvider(id(), startOffset, endOffset); + auto *textRangeProvider = new QWindowsUiaTextRangeProvider(id(), startOffset, endOffset); SafeArrayPutElement(*pRetVal, &i, static_cast<IUnknown *>(textRangeProvider)); textRangeProvider->Release(); } @@ -110,7 +110,7 @@ HRESULT STDMETHODCALLTYPE QWindowsUiaTextProvider::GetSelection(SAFEARRAY **pRet if ((*pRetVal = SafeArrayCreateVector(VT_UNKNOWN, 0, 1))) { LONG i = 0; int cursorPosition = textInterface->cursorPosition(); - QWindowsUiaTextRangeProvider *textRangeProvider = new QWindowsUiaTextRangeProvider(id(), cursorPosition, cursorPosition); + auto *textRangeProvider = new QWindowsUiaTextRangeProvider(id(), cursorPosition, cursorPosition); SafeArrayPutElement(*pRetVal, &i, static_cast<IUnknown *>(textRangeProvider)); textRangeProvider->Release(); } @@ -138,7 +138,7 @@ HRESULT STDMETHODCALLTYPE QWindowsUiaTextProvider::GetVisibleRanges(SAFEARRAY ** // Considering the entire text as visible. if ((*pRetVal = SafeArrayCreateVector(VT_UNKNOWN, 0, 1))) { LONG i = 0; - QWindowsUiaTextRangeProvider *textRangeProvider = new QWindowsUiaTextRangeProvider(id(), 0, textInterface->characterCount()); + auto *textRangeProvider = new QWindowsUiaTextRangeProvider(id(), 0, textInterface->characterCount()); SafeArrayPutElement(*pRetVal, &i, static_cast<IUnknown *>(textRangeProvider)); textRangeProvider->Release(); } diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiatextprovider.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiatextprovider.h index a9be70fa16..ffab48b0e8 100644 --- a/src/plugins/platforms/windows/uiautomation/qwindowsuiatextprovider.h +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiatextprovider.h @@ -52,7 +52,7 @@ QT_BEGIN_NAMESPACE class QWindowsUiaTextProvider : public QWindowsUiaBaseProvider, public QWindowsComBase<ITextProvider2> { - Q_DISABLE_COPY(QWindowsUiaTextProvider) + Q_DISABLE_COPY_MOVE(QWindowsUiaTextProvider) public: explicit QWindowsUiaTextProvider(QAccessible::Id id); ~QWindowsUiaTextProvider(); diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiatextrangeprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiatextrangeprovider.cpp index 1be186f6b3..d8b8f7281d 100644 --- a/src/plugins/platforms/windows/uiautomation/qwindowsuiatextrangeprovider.cpp +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiatextrangeprovider.cpp @@ -48,6 +48,7 @@ #include <QtGui/qaccessible.h> #include <QtCore/qloggingcategory.h> #include <QtCore/qstring.h> +#include <QtCore/qvarlengtharray.h> QT_BEGIN_NAMESPACE @@ -92,7 +93,7 @@ HRESULT QWindowsUiaTextRangeProvider::Compare(ITextRangeProvider *range, BOOL *p if (!range || !pRetVal) return E_INVALIDARG; - QWindowsUiaTextRangeProvider *targetProvider = static_cast<QWindowsUiaTextRangeProvider *>(range); + auto *targetProvider = static_cast<QWindowsUiaTextRangeProvider *>(range); *pRetVal = ((targetProvider->m_startOffset == m_startOffset) && (targetProvider->m_endOffset == m_endOffset)); return S_OK; } @@ -110,7 +111,7 @@ HRESULT QWindowsUiaTextRangeProvider::CompareEndpoints(TextPatternRangeEndpoint if (!targetRange || !pRetVal) return E_INVALIDARG; - QWindowsUiaTextRangeProvider *targetProvider = static_cast<QWindowsUiaTextRangeProvider *>(targetRange); + auto *targetProvider = static_cast<QWindowsUiaTextRangeProvider *>(targetRange); int point = (endpoint == TextPatternRangeEndpoint_Start) ? m_startOffset : m_endOffset; int targetPoint = (targetEndpoint == TextPatternRangeEndpoint_Start) ? @@ -227,7 +228,7 @@ HRESULT QWindowsUiaTextRangeProvider::GetBoundingRectangles(SAFEARRAY **pRetVal) return UIA_E_ELEMENTNOTAVAILABLE; int len = textInterface->characterCount(); - QList<QRect> rectList; + QVarLengthArray<QRect> rectList; if ((m_startOffset >= 0) && (m_endOffset <= len) && (m_startOffset < m_endOffset)) { int start, end; @@ -373,7 +374,7 @@ HRESULT QWindowsUiaTextRangeProvider::MoveEndpointByRange(TextPatternRangeEndpoi qCDebug(lcQpaUiAutomation) << __FUNCTION__ << "endpoint=" << endpoint << "targetRange=" << targetRange << "targetEndpoint=" << targetEndpoint << "this: " << this; - QWindowsUiaTextRangeProvider *targetProvider = static_cast<QWindowsUiaTextRangeProvider *>(targetRange); + auto *targetProvider = static_cast<QWindowsUiaTextRangeProvider *>(targetRange); int targetPoint = (targetEndpoint == TextPatternRangeEndpoint_Start) ? targetProvider->m_startOffset : targetProvider->m_endOffset; diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiatextrangeprovider.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiatextrangeprovider.h index 39b9069fc0..3b4ec63ceb 100644 --- a/src/plugins/platforms/windows/uiautomation/qwindowsuiatextrangeprovider.h +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiatextrangeprovider.h @@ -51,7 +51,7 @@ QT_BEGIN_NAMESPACE class QWindowsUiaTextRangeProvider : public QWindowsUiaBaseProvider, public QWindowsComBase<ITextRangeProvider> { - Q_DISABLE_COPY(QWindowsUiaTextRangeProvider) + Q_DISABLE_COPY_MOVE(QWindowsUiaTextRangeProvider) public: explicit QWindowsUiaTextRangeProvider(QAccessible::Id id, int startOffset, int endOffset); virtual ~QWindowsUiaTextRangeProvider(); diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiatoggleprovider.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiatoggleprovider.h index 2bed6f7e36..892b635b41 100644 --- a/src/plugins/platforms/windows/uiautomation/qwindowsuiatoggleprovider.h +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiatoggleprovider.h @@ -51,7 +51,7 @@ QT_BEGIN_NAMESPACE class QWindowsUiaToggleProvider : public QWindowsUiaBaseProvider, public QWindowsComBase<IToggleProvider> { - Q_DISABLE_COPY(QWindowsUiaToggleProvider) + Q_DISABLE_COPY_MOVE(QWindowsUiaToggleProvider) public: explicit QWindowsUiaToggleProvider(QAccessible::Id id); virtual ~QWindowsUiaToggleProvider(); diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiavalueprovider.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiavalueprovider.h index 334a17e51d..3edfe7a08b 100644 --- a/src/plugins/platforms/windows/uiautomation/qwindowsuiavalueprovider.h +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiavalueprovider.h @@ -52,7 +52,7 @@ QT_BEGIN_NAMESPACE class QWindowsUiaValueProvider : public QWindowsUiaBaseProvider, public QWindowsComBase<IValueProvider> { - Q_DISABLE_COPY(QWindowsUiaValueProvider) + Q_DISABLE_COPY_MOVE(QWindowsUiaValueProvider) public: explicit QWindowsUiaValueProvider(QAccessible::Id id); virtual ~QWindowsUiaValueProvider(); diff --git a/src/plugins/platforms/windows/uiautomation/uiautomation.pri b/src/plugins/platforms/windows/uiautomation/uiautomation.pri index 5d4fa5755b..ee9332e7ea 100644 --- a/src/plugins/platforms/windows/uiautomation/uiautomation.pri +++ b/src/plugins/platforms/windows/uiautomation/uiautomation.pri @@ -41,5 +41,4 @@ HEADERS += \ $$PWD/qwindowsuiawindowprovider.h \ $$PWD/qwindowsuiautils.h -mingw: LIBS *= -luuid - +mingw: QMAKE_USE *= uuid diff --git a/src/plugins/platforms/windows/windows.pri b/src/plugins/platforms/windows/windows.pri index 7004d7e854..95ba961df1 100644 --- a/src/plugins/platforms/windows/windows.pri +++ b/src/plugins/platforms/windows/windows.pri @@ -1,15 +1,21 @@ # Note: OpenGL32 must precede Gdi32 as it overwrites some functions. -LIBS += -lole32 -luser32 -lwinspool -limm32 -lwinmm -loleaut32 +LIBS += -lwinspool -limm32 -loleaut32 QT_FOR_CONFIG += gui qtConfig(opengl):!qtConfig(opengles2):!qtConfig(dynamicgl): LIBS *= -lopengl32 -mingw: LIBS *= -luuid +mingw: QMAKE_USE *= uuid # For the dialog helpers: -LIBS += -lshlwapi -lshell32 -ladvapi32 -lwtsapi32 - -QMAKE_USE_PRIVATE += d3d9/nolink +LIBS += -lshlwapi -lwtsapi32 + +QMAKE_USE_PRIVATE += \ + advapi32 \ + d3d9/nolink \ + ole32 \ + shell32 \ + user32 \ + winmm DEFINES *= QT_NO_CAST_FROM_ASCII QT_NO_FOREACH diff --git a/src/plugins/platforms/windows/windows.pro b/src/plugins/platforms/windows/windows.pro index 174bc7b609..50a3bb41a9 100644 --- a/src/plugins/platforms/windows/windows.pro +++ b/src/plugins/platforms/windows/windows.pro @@ -8,7 +8,8 @@ QT += \ qtConfig(accessibility): QT += accessibility_support-private qtConfig(vulkan): QT += vulkan_support-private -LIBS += -lgdi32 -ldwmapi +LIBS += -ldwmapi +QMAKE_USE_PRIVATE += gdi32 include(windows.pri) diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp index 342e142a74..86ab7651c6 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.cpp +++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp @@ -1091,7 +1091,7 @@ HRESULT QWinRTScreen::onPointerEntered(ICoreWindow *, IPointerEventArgs *args) d->currentTargetWindow = topWindow(); if (d->mouseGrabWindow) - d->currentTargetWindow = d->mouseGrabWindow.load()->window(); + d->currentTargetWindow = d->mouseGrabWindow.loadRelaxed()->window(); qCDebug(lcQpaEvents) << __FUNCTION__ << "handleEnterEvent" << d->currentTargetWindow << pos; QWindowSystemInterface::handleEnterEvent(d->currentTargetWindow, pos, pos); @@ -1115,7 +1115,7 @@ HRESULT QWinRTScreen::onPointerExited(ICoreWindow *, IPointerEventArgs *args) d->touchPoints.remove(id); if (d->mouseGrabWindow) - d->currentTargetWindow = d->mouseGrabWindow.load()->window(); + d->currentTargetWindow = d->mouseGrabWindow.loadRelaxed()->window(); qCDebug(lcQpaEvents) << __FUNCTION__ << "handleLeaveEvent" << d->currentTargetWindow; QWindowSystemInterface::handleLeaveEvent(d->currentTargetWindow); @@ -1146,7 +1146,7 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args) d->currentTargetWindow = windowUnderPointer; if (d->mouseGrabWindow) - d->currentTargetWindow = d->mouseGrabWindow.load()->window(); + d->currentTargetWindow = d->mouseGrabWindow.loadRelaxed()->window(); if (d->currentTargetWindow) { const QPointF globalPosDelta = pos - posPoint; @@ -1348,7 +1348,7 @@ void QWinRTScreen::emulateMouseMove(const QPointF &point, MousePositionTransitio d->currentTargetWindow = windowUnderPointer; if (d->mouseGrabWindow) - d->currentTargetWindow = d->mouseGrabWindow.load()->window(); + d->currentTargetWindow = d->mouseGrabWindow.loadRelaxed()->window(); if (d->currentTargetWindow) { const QPointF globalPosDelta = pos - posPoint; diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiagriditemprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiagriditemprovider.cpp index 524000b618..355dbf7d20 100644 --- a/src/plugins/platforms/winrt/uiautomation/qwinrtuiagriditemprovider.cpp +++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiagriditemprovider.cpp @@ -51,6 +51,8 @@ #include <QtCore/QString> #include <QtCore/private/qeventdispatcher_winrt_p.h> +#include <memory> + QT_BEGIN_NAMESPACE using namespace QWinRTUiAutomation; @@ -105,19 +107,17 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaGridItemProvider::get_ContainingGrid(IIRawEle *value = nullptr; auto accid = id(); - auto elementId = QSharedPointer<QAccessible::Id>(new QAccessible::Id(0)); - auto ptrElementId = new QSharedPointer<QAccessible::Id>(elementId); + auto elementId = std::make_shared<QAccessible::Id>(0); - if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementId]() { + if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, elementId]() { if (QAccessibleInterface *accessible = accessibleForId(accid)) { if (QAccessibleTableCellInterface *tableCellInterface = accessible->tableCellInterface()) { if (QAccessibleInterface *table = tableCellInterface->table()) { - **ptrElementId = idForAccessible(table); - QWinRTUiaMetadataCache::instance()->load(**ptrElementId); + *elementId = idForAccessible(table); + QWinRTUiaMetadataCache::instance()->load(*elementId); } } } - delete ptrElementId; return S_OK; }))) { return E_FAIL; diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiagridprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiagridprovider.cpp index e469991de2..3bd90f6850 100644 --- a/src/plugins/platforms/winrt/uiautomation/qwinrtuiagridprovider.cpp +++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiagridprovider.cpp @@ -51,6 +51,8 @@ #include <QtCore/QString> #include <QtCore/private/qeventdispatcher_winrt_p.h> +#include <memory> + QT_BEGIN_NAMESPACE using namespace QWinRTUiAutomation; @@ -104,21 +106,19 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaGridProvider::GetItem(INT32 row, INT32 column *returnValue = nullptr; auto accid = id(); - auto elementId = QSharedPointer<QAccessible::Id>(new QAccessible::Id(0)); - auto ptrElementId = new QSharedPointer<QAccessible::Id>(elementId); + auto elementId = std::make_shared<QAccessible::Id>(0); - if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, row, column, ptrElementId]() { + if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, row, column, elementId]() { if (QAccessibleInterface *accessible = accessibleForId(accid)) { if (QAccessibleTableInterface *tableInterface = accessible->tableInterface()) { if ((row >= 0) && (row < tableInterface->rowCount()) && (column >= 0) && (column < tableInterface->columnCount())) { if (QAccessibleInterface *cell = tableInterface->cellAt(row, column)) { - **ptrElementId = idForAccessible(cell); - QWinRTUiaMetadataCache::instance()->load(**ptrElementId); + *elementId = idForAccessible(cell); + QWinRTUiaMetadataCache::instance()->load(*elementId); } } } } - delete ptrElementId; return S_OK; }))) { return E_FAIL; diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.cpp index 6f3ad6dcd2..0b1db306bd 100644 --- a/src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.cpp +++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.cpp @@ -64,6 +64,8 @@ #include <QtCore/qfunctions_winrt.h> #include <QtCore/private/qeventdispatcher_winrt_p.h> +#include <memory> + using namespace QWinRTUiAutomation; using namespace Microsoft::WRL; using namespace Microsoft::WRL::Wrappers; @@ -179,7 +181,7 @@ HRESULT QWinRTUiaMainProvider::rawProviderForAccessibleId(QAccessible::Id elemen } // Returns an array of IIRawElementProviderSimple instances for a list of accessible interface ids. -HRESULT QWinRTUiaMainProvider::rawProviderArrayForAccessibleIdList(const QList<QAccessible::Id> &elementIds, +HRESULT QWinRTUiaMainProvider::rawProviderArrayForAccessibleIdList(const QVarLengthArray<QAccessible::Id> &elementIds, UINT32 *returnValueSize, IIRawElementProviderSimple ***returnValue) { @@ -190,7 +192,7 @@ HRESULT QWinRTUiaMainProvider::rawProviderArrayForAccessibleIdList(const QList<Q QList<IIRawElementProviderSimple *> rawProviderList; - for (auto elementId : qAsConst(elementIds)) { + for (auto elementId : elementIds) { IIRawElementProviderSimple *rawProvider; if (SUCCEEDED(rawProviderForAccessibleId(elementId, &rawProvider))) rawProviderList.append(rawProvider); @@ -515,10 +517,9 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetChildrenCore(IVector<Automat *returnValue = nullptr; auto accid = id(); - auto children = QSharedPointer<QList<QAccessible::Id>>(new QList<QAccessible::Id>); - auto ptrChildren = new QSharedPointer<QList<QAccessible::Id>>(children); + auto children = std::make_shared<QVarLengthArray<QAccessible::Id>>(); - if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrChildren]() { + if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, children]() { if (QAccessibleInterface *accessible = accessibleForId(accid)) { int childCount = accessible->childCount(); for (int i = 0; i < childCount; ++i) { @@ -526,11 +527,10 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetChildrenCore(IVector<Automat QAccessible::Id childId = idForAccessible(childAcc); QWinRTUiaMetadataCache::instance()->load(childId); if (!childAcc->state().invisible) - (*ptrChildren)->append(childId); + children->append(childId); } } } - delete ptrChildren; return S_OK; }))) { return E_FAIL; @@ -538,7 +538,7 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetChildrenCore(IVector<Automat ComPtr<IVector<AutomationPeer *>> peerVector = Make<QWinRTUiaPeerVector>(); - for (auto childId : qAsConst(*children)) { + for (auto childId : *children) { if (ComPtr<QWinRTUiaMainProvider> provider = providerForAccessibleId(childId)) { IAutomationPeer *peer; if (SUCCEEDED(provider.CopyTo(&peer))) @@ -750,10 +750,9 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetPeerFromPointCore(ABI::Windo // Scale coordinates from High DPI screens? auto accid = id(); - auto elementId = QSharedPointer<QAccessible::Id>(new QAccessible::Id(0)); - auto ptrElementId = new QSharedPointer<QAccessible::Id>(elementId); + auto elementId = std::make_shared<QAccessible::Id>(0); - if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementId, point]() { + if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, elementId, point]() { // Controls can be embedded within grouping elements. By default returns the innermost control. QAccessibleInterface *target = accessibleForId(accid); while (QAccessibleInterface *tmpacc = target->childAt(point.X, point.Y)) { @@ -761,9 +760,8 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaMainProvider::GetPeerFromPointCore(ABI::Windo // For accessibility tools it may be better to return the text element instead of its subcomponents. if (target->textInterface()) break; } - **ptrElementId = idForAccessible(target); - QWinRTUiaMetadataCache::instance()->load(**ptrElementId); - delete ptrElementId; + *elementId = idForAccessible(target); + QWinRTUiaMetadataCache::instance()->load(*elementId); return S_OK; }))) { return E_FAIL; diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.h b/src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.h index 384a166cf7..23a6e56ae7 100644 --- a/src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.h +++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiamainprovider.h @@ -69,7 +69,7 @@ public: virtual ~QWinRTUiaMainProvider(); static QWinRTUiaMainProvider *providerForAccessibleId(QAccessible::Id id); static HRESULT rawProviderForAccessibleId(QAccessible::Id elementId, ABI::Windows::UI::Xaml::Automation::Provider::IIRawElementProviderSimple **returnValue); - static HRESULT rawProviderArrayForAccessibleIdList(const QList<QAccessible::Id> &elementIds, UINT32 *returnValueSize, ABI::Windows::UI::Xaml::Automation::Provider::IIRawElementProviderSimple ***returnValue); + static HRESULT rawProviderArrayForAccessibleIdList(const QVarLengthArray<QAccessible::Id> &elementIds, UINT32 *returnValueSize, ABI::Windows::UI::Xaml::Automation::Provider::IIRawElementProviderSimple ***returnValue); static void notifyFocusChange(QAccessibleEvent *event); static void notifyVisibilityChange(QAccessibleEvent *event); static void notifyStateChange(QAccessibleStateChangeEvent *event); diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionitemprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionitemprovider.cpp index 9bc88272ba..2cb5aa685c 100644 --- a/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionitemprovider.cpp +++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionitemprovider.cpp @@ -51,6 +51,8 @@ #include <QtCore/QString> #include <QtCore/private/qeventdispatcher_winrt_p.h> +#include <memory> + QT_BEGIN_NAMESPACE using namespace QWinRTUiAutomation; @@ -94,21 +96,19 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaSelectionItemProvider::get_SelectionContainer *value = nullptr; auto accid = id(); - auto elementId = QSharedPointer<QAccessible::Id>(new QAccessible::Id(0)); - auto ptrElementId = new QSharedPointer<QAccessible::Id>(elementId); + auto elementId = std::make_shared<QAccessible::Id>(0); - if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementId]() { + if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, elementId]() { if (QAccessibleInterface *accessible = accessibleForId(accid)) { // Radio buttons do not require a container. if (accessible->role() == QAccessible::ListItem) { if (QAccessibleInterface *parent = accessible->parent()) { if (parent->role() == QAccessible::List) { - **ptrElementId = idForAccessible(parent); + *elementId = idForAccessible(parent); } } } } - delete ptrElementId; return S_OK; }))) { return E_FAIL; diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionprovider.cpp index 9e61a8df61..4d825351c8 100644 --- a/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionprovider.cpp +++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiaselectionprovider.cpp @@ -51,6 +51,8 @@ #include <QtCore/QString> #include <QtCore/private/qeventdispatcher_winrt_p.h> +#include <memory> + QT_BEGIN_NAMESPACE using namespace QWinRTUiAutomation; @@ -89,10 +91,9 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaSelectionProvider::get_IsSelectionRequired(bo *value = false; auto accid = id(); - auto selectionRequired = QSharedPointer<bool>(new bool(false)); - auto ptrSelectionRequired = new QSharedPointer<bool>(selectionRequired); + auto selectionRequired = std::make_shared<bool>(false); - if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrSelectionRequired]() { + if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, selectionRequired]() { // Initially returns false if none are selected. After the first selection, it may be required. bool anySelected = false; if (QAccessibleInterface *accessible = accessibleForId(accid)) { @@ -105,9 +106,8 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaSelectionProvider::get_IsSelectionRequired(bo } } } - **ptrSelectionRequired = anySelected && !accessible->state().multiSelectable && !accessible->state().extSelectable; + *selectionRequired = anySelected && !accessible->state().multiSelectable && !accessible->state().extSelectable; } - delete ptrSelectionRequired; return S_OK; }))) { return E_FAIL; @@ -128,10 +128,9 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaSelectionProvider::GetSelection(UINT32 *retur *returnValue = nullptr; auto accid = id(); - auto elementIds = QSharedPointer<QList<QAccessible::Id>>(new QList<QAccessible::Id>); - auto ptrElementIds = new QSharedPointer<QList<QAccessible::Id>>(elementIds); + auto elementIds = std::make_shared<QVarLengthArray<QAccessible::Id>>(); - if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementIds]() { + if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, elementIds]() { if (QAccessibleInterface *accessible = accessibleForId(accid)) { int childCount = accessible->childCount(); for (int i = 0; i < childCount; ++i) { @@ -139,12 +138,11 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaSelectionProvider::GetSelection(UINT32 *retur if (childAcc->state().selected) { QAccessible::Id childId = idForAccessible(childAcc); QWinRTUiaMetadataCache::instance()->load(childId); - (*ptrElementIds)->append(childId); + elementIds->append(childId); } } } } - delete ptrElementIds; return S_OK; }))) { return E_FAIL; diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableitemprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableitemprovider.cpp index 1af74a8b72..7cd953de87 100644 --- a/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableitemprovider.cpp +++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableitemprovider.cpp @@ -51,6 +51,8 @@ #include <QtCore/QString> #include <QtCore/private/qeventdispatcher_winrt_p.h> +#include <memory> + QT_BEGIN_NAMESPACE using namespace QWinRTUiAutomation; @@ -79,21 +81,19 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTableItemProvider::GetColumnHeaderItems(UINT3 *returnValue = nullptr; auto accid = id(); - auto elementIds = QSharedPointer<QList<QAccessible::Id>>(new QList<QAccessible::Id>); - auto ptrElementIds = new QSharedPointer<QList<QAccessible::Id>>(elementIds); + auto elementIds = std::make_shared<QVarLengthArray<QAccessible::Id>>(); - if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementIds]() { + if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, elementIds]() { if (QAccessibleInterface *accessible = accessibleForId(accid)) { if (QAccessibleTableCellInterface *tableCellInterface = accessible->tableCellInterface()) { QList<QAccessibleInterface *> headers = tableCellInterface->columnHeaderCells(); for (auto header : qAsConst(headers)) { QAccessible::Id headerId = idForAccessible(header); QWinRTUiaMetadataCache::instance()->load(headerId); - (*ptrElementIds)->append(headerId); + elementIds->append(headerId); } } } - delete ptrElementIds; return S_OK; }))) { return E_FAIL; @@ -113,21 +113,19 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTableItemProvider::GetRowHeaderItems(UINT32 * *returnValue = nullptr; auto accid = id(); - auto elementIds = QSharedPointer<QList<QAccessible::Id>>(new QList<QAccessible::Id>); - auto ptrElementIds = new QSharedPointer<QList<QAccessible::Id>>(elementIds); + auto elementIds = std::make_shared<QVarLengthArray<QAccessible::Id>>(); - if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementIds]() { + if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, elementIds]() { if (QAccessibleInterface *accessible = accessibleForId(accid)) { if (QAccessibleTableCellInterface *tableCellInterface = accessible->tableCellInterface()) { QList<QAccessibleInterface *> headers = tableCellInterface->rowHeaderCells(); for (auto header : qAsConst(headers)) { QAccessible::Id headerId = idForAccessible(header); QWinRTUiaMetadataCache::instance()->load(headerId); - (*ptrElementIds)->append(headerId); + elementIds->append(headerId); } } } - delete ptrElementIds; return S_OK; }))) { return E_FAIL; diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableprovider.cpp index e71ade3c1f..d763b320b1 100644 --- a/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableprovider.cpp +++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatableprovider.cpp @@ -51,6 +51,8 @@ #include <QtCore/QString> #include <QtCore/private/qeventdispatcher_winrt_p.h> +#include <memory> + QT_BEGIN_NAMESPACE using namespace QWinRTUiAutomation; @@ -91,10 +93,9 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTableProvider::GetColumnHeaders(UINT32 *retur *returnValue = nullptr; auto accid = id(); - auto elementIds = QSharedPointer<QList<QAccessible::Id>>(new QList<QAccessible::Id>); - auto ptrElementIds = new QSharedPointer<QList<QAccessible::Id>>(elementIds); + auto elementIds = std::make_shared<QVarLengthArray<QAccessible::Id>>(); - if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementIds]() { + if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, elementIds]() { if (QAccessibleInterface *accessible = accessibleForId(accid)) { if (QAccessibleTableInterface *tableInterface = accessible->tableInterface()) { for (int i = 0; i < tableInterface->columnCount(); ++i) { @@ -105,14 +106,13 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTableProvider::GetColumnHeaders(UINT32 *retur for (auto header : qAsConst(headers)) { QAccessible::Id headerId = idForAccessible(header); QWinRTUiaMetadataCache::instance()->load(headerId); - (*ptrElementIds)->append(headerId); + elementIds->append(headerId); } } } } } } - delete ptrElementIds; return S_OK; }))) { return E_FAIL; @@ -132,10 +132,9 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTableProvider::GetRowHeaders(UINT32 *returnVa *returnValue = nullptr; auto accid = id(); - auto elementIds = QSharedPointer<QList<QAccessible::Id>>(new QList<QAccessible::Id>); - auto ptrElementIds = new QSharedPointer<QList<QAccessible::Id>>(elementIds); + auto elementIds = std::make_shared<QVarLengthArray<QAccessible::Id>>(); - if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrElementIds]() { + if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, elementIds]() { if (QAccessibleInterface *accessible = accessibleForId(accid)) { if (QAccessibleTableInterface *tableInterface = accessible->tableInterface()) { for (int i = 0; i < tableInterface->rowCount(); ++i) { @@ -146,14 +145,13 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTableProvider::GetRowHeaders(UINT32 *returnVa for (auto header : qAsConst(headers)) { QAccessible::Id headerId = idForAccessible(header); QWinRTUiaMetadataCache::instance()->load(headerId); - (*ptrElementIds)->append(headerId); + elementIds->append(headerId); } } } } } } - delete ptrElementIds; return S_OK; }))) { return E_FAIL; diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextprovider.cpp index aa120377df..cd7420f360 100644 --- a/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextprovider.cpp +++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextprovider.cpp @@ -51,6 +51,8 @@ #include <QtCore/QString> #include <QtCore/private/qeventdispatcher_winrt_p.h> +#include <memory> + QT_BEGIN_NAMESPACE using namespace QWinRTUiAutomation; @@ -104,26 +106,26 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTextProvider::GetSelection(UINT32 *returnValu *returnValueSize = 0; *returnValue = nullptr; + struct Selection { int startOffset, endOffset; }; + auto accid = id(); - auto selections = QSharedPointer<QList<QPair<int,int>>>(new QList<QPair<int,int>>); - auto ptrSelections = new QSharedPointer<QList<QPair<int,int>>>(selections); + auto selections = std::make_shared<QVarLengthArray<Selection>>(); - if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, ptrSelections]() { + if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, selections]() { if (QAccessibleInterface *accessible = accessibleForId(accid)) { if (QAccessibleTextInterface *textInterface = accessible->textInterface()) { for (int i = 0; i < textInterface->selectionCount(); ++i) { - QPair<int,int> sel; - textInterface->selection(i, &sel.first, &sel.second); - (*ptrSelections)->append(sel); + int startOffset, endOffset; + textInterface->selection(i, &startOffset, &endOffset); + selections->append({startOffset, endOffset}); } - if ((*ptrSelections)->size() == 0) { + if (selections->size() == 0) { // If there is no selection, we return an array with a single degenerate (empty) text range at the cursor position. - QPair<int,int> sel(textInterface->cursorPosition(), textInterface->cursorPosition()); - (*ptrSelections)->append(sel); + auto cur = textInterface->cursorPosition(); + selections->append({cur, cur}); } } } - delete ptrSelections; return S_OK; }))) { return E_FAIL; @@ -137,9 +139,11 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTextProvider::GetSelection(UINT32 *returnValu if (!providerArray) return E_OUTOFMEMORY; - for (int i = 0; i < selCount; ++i) { - ComPtr<QWinRTUiaTextRangeProvider> textRangeProvider = Make<QWinRTUiaTextRangeProvider>(id(), (*selections)[i].first, (*selections)[i].second); - textRangeProvider.CopyTo(&providerArray[i]); + auto dst = providerArray; + for (auto sel : *selections) { + ComPtr<QWinRTUiaTextRangeProvider> textRangeProvider + = Make<QWinRTUiaTextRangeProvider>(id(), sel.startOffset, sel.endOffset); + textRangeProvider.CopyTo(dst++); } *returnValueSize = selCount; *returnValue = providerArray; @@ -184,14 +188,12 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTextProvider::RangeFromPoint(ABI::Windows::Fo const QPoint pt(screenLocation.X, screenLocation.Y); auto accid = id(); - auto offset = QSharedPointer<int>(new int); - auto ptrOffset = new QSharedPointer<int>(offset); + auto offset = std::make_shared<int>(); - if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, pt, ptrOffset]() { + if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, pt, offset]() { if (QAccessibleInterface *accessible = accessibleForId(accid)) if (QAccessibleTextInterface *textInterface = accessible->textInterface()) - **ptrOffset = qBound(0, textInterface->offsetAtPoint(pt), textInterface->characterCount() - 1); - delete ptrOffset; + *offset = qBound(0, textInterface->offsetAtPoint(pt), textInterface->characterCount() - 1); return S_OK; }))) { return E_FAIL; diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextrangeprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextrangeprovider.cpp index fc3778d652..ca15feaff9 100644 --- a/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextrangeprovider.cpp +++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiatextrangeprovider.cpp @@ -51,6 +51,8 @@ #include <QtCore/QString> #include <QtCore/private/qeventdispatcher_winrt_p.h> +#include <memory> + QT_BEGIN_NAMESPACE using namespace QWinRTUiAutomation; @@ -212,10 +214,9 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::GetBoundingRectangles(UINT auto accid = id(); auto startOffset = m_startOffset; auto endOffset = m_endOffset; - auto rects = QSharedPointer<QList<QRect>>(new QList<QRect>); - auto ptrRects = new QSharedPointer<QList<QRect>>(rects); + auto rects = std::make_shared<QVarLengthArray<QRect>>(); - if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, startOffset, endOffset, ptrRects]() { + if (!SUCCEEDED(QEventDispatcherWinRT::runOnMainThread([accid, startOffset, endOffset, rects]() { if (QAccessibleInterface *accessible = accessibleForId(accid)) { if (QAccessibleTextInterface *textInterface = accessible->textInterface()) { int len = textInterface->characterCount(); @@ -233,7 +234,7 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::GetBoundingRectangles(UINT qMin(startRect.y(), endRect.y()), qMax(startRect.x() + startRect.width(), endRect.x() + endRect.width()) - qMin(startRect.x(), endRect.x()), qMax(startRect.y() + startRect.height(), endRect.y() + endRect.height()) - qMin(startRect.y(), endRect.y())); - (*ptrRects)->append(lineRect); + rects->append(lineRect); } if (end >= len) break; textInterface->textAfterOffset(end + 1, QAccessible::LineBoundary, &start, &end); @@ -241,7 +242,6 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::GetBoundingRectangles(UINT } } } - delete ptrRects; return S_OK; }))) { return E_FAIL; @@ -251,11 +251,12 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaTextRangeProvider::GetBoundingRectangles(UINT if (!doubleArray) return E_OUTOFMEMORY; - for (int i = 0; i < rects->size(); ++i) { - doubleArray[i*4] = (*rects)[i].left(); - doubleArray[i*4+1] = (*rects)[i].top(); - doubleArray[i*4+2] = (*rects)[i].width(); - doubleArray[i*4+3] = (*rects)[i].height(); + DOUBLE *dst = doubleArray; + for (auto rect : *rects) { + *dst++ = rect.left(); + *dst++ = rect.top(); + *dst++ = rect.width(); + *dst++ = rect.height(); } *returnValue = doubleArray; *returnValueSize = 4 * rects->size(); diff --git a/src/plugins/platforms/winrt/uiautomation/qwinrtuiavalueprovider.cpp b/src/plugins/platforms/winrt/uiautomation/qwinrtuiavalueprovider.cpp index 21389b74d2..255d8ee49e 100644 --- a/src/plugins/platforms/winrt/uiautomation/qwinrtuiavalueprovider.cpp +++ b/src/plugins/platforms/winrt/uiautomation/qwinrtuiavalueprovider.cpp @@ -96,24 +96,22 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaValueProvider::SetValue(HSTRING value) qCDebug(lcQpaUiAutomation) << __FUNCTION__; auto accid = id(); - auto tmpValue = QSharedPointer<QString>(new QString); - auto ptrValue = new QSharedPointer<QString>(tmpValue); - *tmpValue = hStrToQStr(value); + QString tmpValue = hStrToQStr(value); - QEventDispatcherWinRT::runOnMainThread([accid, ptrValue]() { + QEventDispatcherWinRT::runOnMainThread([accid, tmpValue]() { if (QAccessibleInterface *accessible = accessibleForId(accid)) { // First sets the value as a text. - accessible->setText(QAccessible::Value, **ptrValue); + accessible->setText(QAccessible::Value, tmpValue); // Then, if the control supports the value interface (range value) // and the supplied text can be converted to a number, and that number // lies within the min/max limits, sets it as the control's current (numeric) value. if (QAccessibleValueInterface *valueInterface = accessible->valueInterface()) { bool ok = false; - double numval = (*ptrValue)->toDouble(&ok); + double numval = tmpValue.toDouble(&ok); if (ok) { double minimum = valueInterface->minimumValue().toDouble(); double maximum = valueInterface->maximumValue().toDouble(); @@ -124,7 +122,6 @@ HRESULT STDMETHODCALLTYPE QWinRTUiaValueProvider::SetValue(HSTRING value) } } QWinRTUiaMetadataCache::instance()->load(accid); - delete ptrValue; return S_OK; }, 0); diff --git a/src/plugins/platforms/winrt/winrt.pro b/src/plugins/platforms/winrt/winrt.pro index 43132a1a76..43dc8f074c 100644 --- a/src/plugins/platforms/winrt/winrt.pro +++ b/src/plugins/platforms/winrt/winrt.pro @@ -8,8 +8,7 @@ QT += \ DEFINES *= QT_NO_CAST_FROM_ASCII __WRL_NO_DEFAULT_LIB__ -LIBS += -lws2_32 -QMAKE_USE_PRIVATE += d3d11 +QMAKE_USE_PRIVATE += d3d11 ws2_32 SOURCES = \ main.cpp \ diff --git a/src/plugins/platforms/xcb/gl_integrations/qxcbglintegrationplugin.h b/src/plugins/platforms/xcb/gl_integrations/qxcbglintegrationplugin.h index d5a0af97b0..b18248570f 100644 --- a/src/plugins/platforms/xcb/gl_integrations/qxcbglintegrationplugin.h +++ b/src/plugins/platforms/xcb/gl_integrations/qxcbglintegrationplugin.h @@ -54,7 +54,7 @@ class Q_XCB_EXPORT QXcbGlIntegrationPlugin : public QObject { Q_OBJECT public: - explicit QXcbGlIntegrationPlugin(QObject *parent = 0) + explicit QXcbGlIntegrationPlugin(QObject *parent = nullptr) : QObject(parent) { } diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxintegration.cpp b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxintegration.cpp index b751aaf8a3..34895caaa2 100644 --- a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxintegration.cpp +++ b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxintegration.cpp @@ -164,7 +164,11 @@ bool QXcbGlxIntegration::handleXcbEvent(xcb_generic_event_t *event, uint respons XUnlockDisplay(xdisplay); locked = false; auto eventType = m_connection->nativeInterface()->nativeEventType(); +# if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + qintptr result = 0; +# else long result = 0; +# endif handled = dispatcher->filterNativeEvent(eventType, &ev, &result); } #endif diff --git a/src/plugins/platforms/xcb/nativepainting/qpaintengine_x11.cpp b/src/plugins/platforms/xcb/nativepainting/qpaintengine_x11.cpp index 8d958aae94..82b6d60bcd 100644 --- a/src/plugins/platforms/xcb/nativepainting/qpaintengine_x11.cpp +++ b/src/plugins/platforms/xcb/nativepainting/qpaintengine_x11.cpp @@ -455,7 +455,7 @@ static const uchar base_dither_matrix[DITHER_SIZE][DITHER_SIZE] = { static QPixmap qt_patternForAlpha(uchar alpha, int screen) { QPixmap pm; - QString key = QLatin1Literal("$qt-alpha-brush$") + QString key = QLatin1String("$qt-alpha-brush$") % HexString<uchar>(alpha) % HexString<int>(screen); diff --git a/src/plugins/platforms/xcb/nativepainting/qpixmap_x11.cpp b/src/plugins/platforms/xcb/nativepainting/qpixmap_x11.cpp index b1ce39f363..f86bedbdcd 100644 --- a/src/plugins/platforms/xcb/nativepainting/qpixmap_x11.cpp +++ b/src/plugins/platforms/xcb/nativepainting/qpixmap_x11.cpp @@ -2017,7 +2017,7 @@ QImage QX11PlatformPixmap::toImage(const QXImageWrapper &xiWrapper, const QRect } } else if (xi->bits_per_pixel == d) { // compatible depth char *xidata = xi->data; // copy each scanline - int bpl = qMin(image.bytesPerLine(),xi->bytes_per_line); + int bpl = qMin(int(image.bytesPerLine()),xi->bytes_per_line); for (int y=0; y<xi->height; y++) { memcpy(image.scanLine(y), xidata, bpl); xidata += xi->bytes_per_line; diff --git a/src/plugins/platforms/xcb/nativepainting/qt_x11_p.h b/src/plugins/platforms/xcb/nativepainting/qt_x11_p.h index a13a8f0483..1f7e7cf49b 100644 --- a/src/plugins/platforms/xcb/nativepainting/qt_x11_p.h +++ b/src/plugins/platforms/xcb/nativepainting/qt_x11_p.h @@ -190,7 +190,7 @@ struct QX11InfoData { }; template <class T> -Q_DECL_RELAXED_CONSTEXPR inline int lowest_bit(T v) Q_DECL_NOTHROW +Q_DECL_RELAXED_CONSTEXPR inline int lowest_bit(T v) noexcept { int result = qCountTrailingZeroBits(v); return ((result >> 3) == sizeof(T)) ? -1 : result; diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index f98b2dfe3a..cac6345b66 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -440,7 +440,11 @@ const char *xcb_protocol_request_codes[] = void QXcbConnection::handleXcbError(xcb_generic_error_t *error) { +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + qintptr result = 0; +#else long result = 0; +#endif QAbstractEventDispatcher* dispatcher = QAbstractEventDispatcher::instance(); if (dispatcher && dispatcher->filterNativeEvent(m_nativeInterface->nativeEventType(), error, &result)) return; @@ -537,7 +541,11 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event) if (Q_UNLIKELY(lcQpaEvents().isDebugEnabled())) printXcbEvent(lcQpaEvents(), "Event", event); +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + qintptr result = 0; // Used only by MS Windows +#else long result = 0; // Used only by MS Windows +#endif if (QAbstractEventDispatcher *dispatcher = QAbstractEventDispatcher::instance()) { if (dispatcher->filterNativeEvent(m_nativeInterface->nativeEventType(), event, &result)) return; diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index bbfa252881..7cf25d41a6 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -108,7 +108,7 @@ public: virtual void handleXIMouseEvent(xcb_ge_event_t *, Qt::MouseEventSource = Qt::MouseEventNotSynthesized) {} virtual void handleXIEnterLeave(xcb_ge_event_t *) {} #endif - virtual QXcbWindow *toWindow() { return 0; } + virtual QXcbWindow *toWindow() { return nullptr; } }; typedef QHash<xcb_window_t, QXcbWindowEventListener *> WindowMapper; @@ -366,7 +366,7 @@ private: WindowMapper m_mapper; - Qt::MouseButtons m_buttonState = 0; + Qt::MouseButtons m_buttonState = nullptr; Qt::MouseButton m_button = Qt::NoButton; QXcbWindow *m_focusWindow = nullptr; diff --git a/src/plugins/platforms/xcb/qxcbconnection_basic.h b/src/plugins/platforms/xcb/qxcbconnection_basic.h index b979129cba..1bd4310562 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_basic.h +++ b/src/plugins/platforms/xcb/qxcbconnection_basic.h @@ -163,7 +163,7 @@ private: #define Q_XCB_REPLY_CONNECTION_ARG(connection, ...) connection struct QStdFreeDeleter { - void operator()(void *p) const Q_DECL_NOTHROW { return std::free(p); } + void operator()(void *p) const noexcept { return std::free(p); } }; #define Q_XCB_REPLY(call, ...) \ diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index bc09fe2f91..4639185416 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -997,8 +997,8 @@ void QXcbConnection::xi2HandleScrollEvent(void *event, ScrollingDevice &scrollin QPoint global(fixed1616ToReal(xiDeviceEvent->root_x), fixed1616ToReal(xiDeviceEvent->root_y)); Qt::KeyboardModifiers modifiers = keyboard()->translateModifiers(xiDeviceEvent->mods.effective); if (modifiers & Qt::AltModifier) { - std::swap(angleDelta.rx(), angleDelta.ry()); - std::swap(rawDelta.rx(), rawDelta.ry()); + angleDelta = angleDelta.transposed(); + rawDelta = rawDelta.transposed(); } qCDebug(lcQpaXInputEvents) << "scroll wheel @ window pos" << local << "delta px" << rawDelta << "angle" << angleDelta; QWindowSystemInterface::handleWheelEvent(platformWindow->window(), xiDeviceEvent->time, local, global, rawDelta, angleDelta, modifiers); @@ -1024,7 +1024,7 @@ void QXcbConnection::xi2HandleScrollEvent(void *event, ScrollingDevice &scrollin QPoint global(fixed1616ToReal(xiDeviceEvent->root_x), fixed1616ToReal(xiDeviceEvent->root_y)); Qt::KeyboardModifiers modifiers = keyboard()->translateModifiers(xiDeviceEvent->mods.effective); if (modifiers & Qt::AltModifier) - std::swap(angleDelta.rx(), angleDelta.ry()); + angleDelta = angleDelta.transposed(); qCDebug(lcQpaXInputEvents) << "scroll wheel (button" << xiDeviceEvent->detail << ") @ window pos" << local << "delta angle" << angleDelta; QWindowSystemInterface::handleWheelEvent(platformWindow->window(), xiDeviceEvent->time, local, global, QPoint(), angleDelta, modifiers); } diff --git a/src/plugins/platforms/xcb/qxcbcursor.h b/src/plugins/platforms/xcb/qxcbcursor.h index 5bc806381c..0b238823f0 100644 --- a/src/plugins/platforms/xcb/qxcbcursor.h +++ b/src/plugins/platforms/xcb/qxcbcursor.h @@ -65,7 +65,7 @@ inline bool operator==(const QXcbCursorCacheKey &k1, const QXcbCursorCacheKey &k return k1.shape == k2.shape && k1.bitmapCacheKey == k2.bitmapCacheKey && k1.maskCacheKey == k2.maskCacheKey; } -inline uint qHash(const QXcbCursorCacheKey &k, uint seed) Q_DECL_NOTHROW +inline uint qHash(const QXcbCursorCacheKey &k, uint seed) noexcept { return (uint(k.shape) + uint(k.bitmapCacheKey) + uint(k.maskCacheKey)) ^ seed; } @@ -83,7 +83,7 @@ public: QPoint pos() const override; void setPos(const QPoint &pos) override; - static void queryPointer(QXcbConnection *c, QXcbVirtualDesktop **virtualDesktop, QPoint *pos, int *keybMask = 0); + static void queryPointer(QXcbConnection *c, QXcbVirtualDesktop **virtualDesktop, QPoint *pos, int *keybMask = nullptr); #ifndef QT_NO_CURSOR xcb_cursor_t xcbCursor(const QCursor &c) const diff --git a/src/plugins/platforms/xcb/qxcbdrag.h b/src/plugins/platforms/xcb/qxcbdrag.h index c19008c04b..1388e68acc 100644 --- a/src/plugins/platforms/xcb/qxcbdrag.h +++ b/src/plugins/platforms/xcb/qxcbdrag.h @@ -86,7 +86,7 @@ public: void handlePosition(QPlatformWindow *w, const xcb_client_message_event_t *event); void handleLeave(QPlatformWindow *w, const xcb_client_message_event_t *event); void handleDrop(QPlatformWindow *, const xcb_client_message_event_t *event, - Qt::MouseButtons b = 0, Qt::KeyboardModifiers mods = 0); + Qt::MouseButtons b = nullptr, Qt::KeyboardModifiers mods = nullptr); void handleStatus(const xcb_client_message_event_t *event); void handleSelectionRequest(const xcb_selection_request_event_t *event); @@ -109,7 +109,7 @@ private: void init(); void handle_xdnd_position(QPlatformWindow *w, const xcb_client_message_event_t *event, - Qt::MouseButtons b = 0, Qt::KeyboardModifiers mods = 0); + Qt::MouseButtons b = nullptr, Qt::KeyboardModifiers mods = nullptr); void handle_xdnd_status(const xcb_client_message_event_t *event); void send_leave(); diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp index 899081e752..81b889a80f 100644 --- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp +++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp @@ -636,13 +636,13 @@ static void dumpNativeWindowsRecursion(const QXcbConnection *connection, xcb_win const QChar oldPadChar =str.padChar(); str.setFieldWidth(8); str.setPadChar(QLatin1Char('0')); - str << hex << window; + str << Qt::hex << window; str.setFieldWidth(oldFieldWidth); str.setPadChar(oldPadChar); - str << dec << " \"" + str << Qt::dec << " \"" << QXcbWindow::windowTitle(connection, window) << "\" " - << geom.width() << 'x' << geom.height() << forcesign << geom.x() << geom.y() - << noforcesign << '\n'; + << geom.width() << 'x' << geom.height() << Qt::forcesign << geom.x() << geom.y() + << Qt::noforcesign << '\n'; auto reply = Q_XCB_REPLY(xcb_query_tree, conn, window); if (reply) { diff --git a/src/plugins/platforms/xcb/qxcbobject.h b/src/plugins/platforms/xcb/qxcbobject.h index 1b98d9346b..931bed9ec1 100644 --- a/src/plugins/platforms/xcb/qxcbobject.h +++ b/src/plugins/platforms/xcb/qxcbobject.h @@ -47,7 +47,7 @@ QT_BEGIN_NAMESPACE class QXcbObject { public: - QXcbObject(QXcbConnection *connection = 0) : m_connection(connection) {} + QXcbObject(QXcbConnection *connection = nullptr) : m_connection(connection) {} void setConnection(QXcbConnection *connection) { m_connection = connection; } QXcbConnection *connection() const { return m_connection; } diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp index 0cf0942dab..8da299d491 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.cpp +++ b/src/plugins/platforms/xcb/qxcbscreen.cpp @@ -660,10 +660,6 @@ QImage::Format QXcbScreen::format() const int QXcbScreen::forcedDpi() const { - static const int overrideDpi = qEnvironmentVariableIntValue("QT_FONT_DPI"); - if (overrideDpi) - return overrideDpi; - const int forcedDpi = m_virtualDesktop->forcedDpi(); if (forcedDpi > 0) return forcedDpi; @@ -679,11 +675,6 @@ QDpi QXcbScreen::logicalDpi() const return m_virtualDesktop->dpi(); } -qreal QXcbScreen::pixelDensity() const -{ - return m_pixelDensity; -} - QPlatformCursor *QXcbScreen::cursor() const { return m_cursor; @@ -747,14 +738,6 @@ void QXcbScreen::updateGeometry(const QRect &geometry, uint8_t rotation) if (m_sizeMillimeters.isEmpty()) m_sizeMillimeters = sizeInMillimeters(geometry.size(), m_virtualDesktop->dpi()); - qreal dpi = forcedDpi(); - if (dpi <= 0) - dpi = geometry.width() / physicalSize().width() * qreal(25.4); - - // Use 128 as a reference DPI on small screens. This favors "small UI" over "large UI". - qreal referenceDpi = physicalSize().width() <= 320 ? 128 : 96; - - m_pixelDensity = qMax(1, qRound(dpi/referenceDpi)); m_geometry = geometry; m_availableGeometry = geometry & m_virtualDesktop->workArea(); QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), m_geometry, m_availableGeometry); @@ -925,7 +908,7 @@ QByteArray QXcbScreen::getEdid() const static inline void formatRect(QDebug &debug, const QRect r) { debug << r.width() << 'x' << r.height() - << forcesign << r.x() << r.y() << noforcesign; + << Qt::forcesign << r.x() << r.y() << Qt::noforcesign; } static inline void formatSizeF(QDebug &debug, const QSizeF s) @@ -939,7 +922,7 @@ QDebug operator<<(QDebug debug, const QXcbScreen *screen) debug.nospace(); debug << "QXcbScreen(" << (const void *)screen; if (screen) { - debug << fixed << qSetRealNumberPrecision(1); + debug << Qt::fixed << qSetRealNumberPrecision(1); debug << ", name=" << screen->name(); debug << ", geometry="; formatRect(debug, screen->geometry()); @@ -957,7 +940,7 @@ QDebug operator<<(QDebug debug, const QXcbScreen *screen) debug << "), orientation=" << screen->orientation(); debug << ", depth=" << screen->depth(); debug << ", refreshRate=" << screen->refreshRate(); - debug << ", root=" << hex << screen->root(); + debug << ", root=" << Qt::hex << screen->root(); debug << ", windowManagerName=" << screen->windowManagerName(); } debug << ')'; diff --git a/src/plugins/platforms/xcb/qxcbscreen.h b/src/plugins/platforms/xcb/qxcbscreen.h index 914ce6307d..79698b4ef3 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.h +++ b/src/plugins/platforms/xcb/qxcbscreen.h @@ -161,7 +161,7 @@ public: QImage::Format format() const override; QSizeF physicalSize() const override { return m_sizeMillimeters; } QDpi logicalDpi() const override; - qreal pixelDensity() const override; + QDpi logicalBaseDpi() const override { return QDpi(96, 96); }; QPlatformCursor *cursor() const override; qreal refreshRate() const override { return m_refreshRate; } Qt::ScreenOrientation orientation() const override { return m_orientation; } @@ -227,7 +227,6 @@ private: Qt::ScreenOrientation m_orientation = Qt::PrimaryOrientation; QXcbCursor *m_cursor; qreal m_refreshRate = 60.0; - int m_pixelDensity = 1; QEdidParser m_edid; }; diff --git a/src/plugins/platforms/xcb/qxcbsessionmanager.cpp b/src/plugins/platforms/xcb/qxcbsessionmanager.cpp index 2303ccf806..f880d4d722 100644 --- a/src/plugins/platforms/xcb/qxcbsessionmanager.cpp +++ b/src/plugins/platforms/xcb/qxcbsessionmanager.cpp @@ -42,6 +42,8 @@ #ifndef QT_NO_SESSIONMANAGER +#include <qpa/qwindowsysteminterface.h> + #include <qguiapplication.h> #include <qdatetime.h> #include <qfileinfo.h> @@ -289,8 +291,7 @@ static void sm_dieCallback(SmcConn smcConn, SmPointer /* clientData */) if (smcConn != smcConnection) return; resetSmState(); - QEvent quitEvent(QEvent::Quit); - QGuiApplication::sendEvent(qApp, &quitEvent); + QWindowSystemInterface::handleApplicationTermination<QWindowSystemInterface::SynchronousDelivery>(); } static void sm_shutdownCancelledCallback(SmcConn smcConn, SmPointer clientData) diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 610eca06a5..97da420798 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -1657,7 +1657,11 @@ bool QXcbWindow::requestSystemTrayWindowDock() bool QXcbWindow::handleNativeEvent(xcb_generic_event_t *event) { auto eventType = connection()->nativeInterface()->nativeEventType(); +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + qintptr result = 0; // Used only by MS Windows +#else long result = 0; // Used only by MS Windows +#endif return QWindowSystemInterface::handleNativeEvent(window(), eventType, event, &result); } @@ -1904,7 +1908,7 @@ void QXcbWindow::handleButtonPressEvent(int event_x, int event_y, int root_x, in else if (detail == 7) angleDelta.setX(-120); if (modifiers & Qt::AltModifier) - std::swap(angleDelta.rx(), angleDelta.ry()); + angleDelta = angleDelta.transposed(); QWindowSystemInterface::handleWheelEvent(window(), timestamp, local, global, QPoint(), angleDelta, modifiers); #if QT_CONFIG(xcb_xinput) } diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h index 8258cc2dfa..5de5974ca7 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -166,7 +166,7 @@ public: bool needsSync() const; void postSyncWindowRequest(); - void clearSyncWindowRequest() { m_pendingSyncRequest = 0; } + void clearSyncWindowRequest() { m_pendingSyncRequest = nullptr; } QXcbScreen *xcbScreen() const; diff --git a/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.h b/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.h index 3497c6a6f1..5cfc4df0d0 100644 --- a/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.h +++ b/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.h @@ -72,7 +72,7 @@ public: QPixmap standardPixmap(StandardPixmap sp, const QSizeF &size) const override; QIcon fileIcon(const QFileInfo &fileInfo, - QPlatformTheme::IconOptions iconOptions = 0) const override; + QPlatformTheme::IconOptions iconOptions = nullptr) const override; QIconEngine *createIconEngine(const QString &iconName) const override; diff --git a/src/plugins/printsupport/windows/windows.pro b/src/plugins/printsupport/windows/windows.pro index 06694fb7fe..6ca601b2a4 100644 --- a/src/plugins/printsupport/windows/windows.pro +++ b/src/plugins/printsupport/windows/windows.pro @@ -18,7 +18,8 @@ HEADERS += \ OTHER_FILES += windows.json -LIBS += -lwinspool -lcomdlg32 -lgdi32 -luser32 +LIBS += -lwinspool -lcomdlg32 +QMAKE_USE_PRIVATE += user32 gdi32 PLUGIN_TYPE = printsupport PLUGIN_CLASS_NAME = QWindowsPrinterSupportPlugin diff --git a/src/plugins/sqldrivers/ibase/qsql_ibase.cpp b/src/plugins/sqldrivers/ibase/qsql_ibase.cpp index ead08dbce8..0f39f6aa0d 100644 --- a/src/plugins/sqldrivers/ibase/qsql_ibase.cpp +++ b/src/plugins/sqldrivers/ibase/qsql_ibase.cpp @@ -40,6 +40,7 @@ #include "qsql_ibase_p.h" #include <qcoreapplication.h> #include <qdatetime.h> +#include <qdeadlinetimer.h> #include <qvariant.h> #include <qsqlerror.h> #include <qsqlfield.h> @@ -1570,10 +1571,9 @@ void QIBaseDriver::close() d->eventBuffers.clear(); #if defined(FB_API_VER) - // Workaround for Firebird crash - QTime timer; - timer.start(); - while (timer.elapsed() < 500) + // TODO check whether this workaround for Firebird crash is still needed + QDeadlineTimer timer(500); + while (!timer.hasExpired()) QCoreApplication::processEvents(); #endif } diff --git a/src/plugins/sqldrivers/odbc/qsql_odbc_p.h b/src/plugins/sqldrivers/odbc/qsql_odbc_p.h index ea0aa6fc8b..ccd0206f38 100644 --- a/src/plugins/sqldrivers/odbc/qsql_odbc_p.h +++ b/src/plugins/sqldrivers/odbc/qsql_odbc_p.h @@ -89,8 +89,8 @@ class Q_EXPORT_SQLDRIVER_ODBC QODBCDriver : public QSqlDriver friend class QODBCResultPrivate; public: - explicit QODBCDriver(QObject *parent=0); - QODBCDriver(SQLHANDLE env, SQLHANDLE con, QObject * parent=0); + explicit QODBCDriver(QObject *parent=nullptr); + QODBCDriver(SQLHANDLE env, SQLHANDLE con, QObject * parent=nullptr); virtual ~QODBCDriver(); bool hasFeature(DriverFeature f) const override; void close() override; diff --git a/src/plugins/sqldrivers/psql/qsql_psql.cpp b/src/plugins/sqldrivers/psql/qsql_psql.cpp index c1be91cb22..760685f64b 100644 --- a/src/plugins/sqldrivers/psql/qsql_psql.cpp +++ b/src/plugins/sqldrivers/psql/qsql_psql.cpp @@ -428,12 +428,14 @@ static QVariant::Type qDecodePSQLType(int t) void QPSQLResultPrivate::deallocatePreparedStmt() { - const QString stmt = QStringLiteral("DEALLOCATE ") + preparedStmtId; - PGresult *result = drv_d_func()->exec(stmt); + if (drv_d_func()) { + const QString stmt = QStringLiteral("DEALLOCATE ") + preparedStmtId; + PGresult *result = drv_d_func()->exec(stmt); - if (PQresultStatus(result) != PGRES_COMMAND_OK) - qWarning("Unable to free statement: %s", PQerrorMessage(drv_d_func()->connection)); - PQclear(result); + if (PQresultStatus(result) != PGRES_COMMAND_OK) + qWarning("Unable to free statement: %s", PQerrorMessage(drv_d_func()->connection)); + PQclear(result); + } preparedStmtId.clear(); } @@ -810,8 +812,8 @@ QSqlRecord QPSQLResult::record() const return info; int count = PQnfields(d->result); + QSqlField f; for (int i = 0; i < count; ++i) { - QSqlField f; if (d->drv_d_func()->isUtf8) f.setName(QString::fromUtf8(PQfname(d->result, i))); else @@ -831,6 +833,8 @@ QSqlRecord QPSQLResult::record() const } } f.setTableName(tableName); + } else { + f.setTableName(QString()); } int ptype = PQftype(d->result, i); f.setType(qDecodePSQLType(ptype)); @@ -1074,8 +1078,10 @@ static QPSQLDriver::Protocol qMakePSQLVersion(int vMaj, int vMin) return QPSQLDriver::Version10; case 11: return QPSQLDriver::Version11; + case 12: + return QPSQLDriver::Version12; default: - if (vMaj > 11) + if (vMaj > 12) return QPSQLDriver::UnknownLaterVersion; break; } @@ -1435,26 +1441,29 @@ QSqlRecord QPSQLDriver::record(const QString &tablename) const schema = stripDelimiters(schema, QSqlDriver::TableName); tbl = stripDelimiters(tbl, QSqlDriver::TableName); - QString stmt = QStringLiteral("SELECT pg_attribute.attname, pg_attribute.atttypid::int, " - "pg_attribute.attnotnull, pg_attribute.attlen, pg_attribute.atttypmod, " - "pg_attrdef.adsrc " - "FROM pg_class, pg_attribute " - "LEFT JOIN pg_attrdef ON (pg_attrdef.adrelid = " - "pg_attribute.attrelid AND pg_attrdef.adnum = pg_attribute.attnum) " - "WHERE %1 " - "AND pg_class.relname = '%2' " - "AND pg_attribute.attnum > 0 " - "AND pg_attribute.attrelid = pg_class.oid " - "AND pg_attribute.attisdropped = false " - "ORDER BY pg_attribute.attnum"); - if (schema.isEmpty()) - stmt = stmt.arg(QStringLiteral("pg_table_is_visible(pg_class.oid)")); - else - stmt = stmt.arg(QStringLiteral("pg_class.relnamespace = (SELECT oid FROM " - "pg_namespace WHERE pg_namespace.nspname = '%1')").arg(schema)); + const QString adsrc = protocol() < Version8 + ? QStringLiteral("pg_attrdef.adsrc") + : QStringLiteral("pg_get_expr(pg_attrdef.adbin, pg_attrdef.adrelid)"); + const QString nspname = schema.isEmpty() + ? QStringLiteral("pg_table_is_visible(pg_class.oid)") + : QStringLiteral("pg_class.relnamespace = (SELECT oid FROM " + "pg_namespace WHERE pg_namespace.nspname = '%1')").arg(schema); + const QString stmt = + QStringLiteral("SELECT pg_attribute.attname, pg_attribute.atttypid::int, " + "pg_attribute.attnotnull, pg_attribute.attlen, pg_attribute.atttypmod, " + "%1 " + "FROM pg_class, pg_attribute " + "LEFT JOIN pg_attrdef ON (pg_attrdef.adrelid = " + "pg_attribute.attrelid AND pg_attrdef.adnum = pg_attribute.attnum) " + "WHERE %2 " + "AND pg_class.relname = '%3' " + "AND pg_attribute.attnum > 0 " + "AND pg_attribute.attrelid = pg_class.oid " + "AND pg_attribute.attisdropped = false " + "ORDER BY pg_attribute.attnum").arg(adsrc, nspname, tbl); QSqlQuery query(createResult()); - query.exec(stmt.arg(tbl)); + query.exec(stmt); while (query.next()) { int len = query.value(3).toInt(); int precision = query.value(4).toInt(); @@ -1506,7 +1515,7 @@ QString QPSQLDriver::formatValue(const QSqlField &field, bool trimStrings) const // this is safe since postgresql stores only the UTC value and not the timezone offset (only used // while parsing), so we have correct behavior in both case of with timezone and without tz r = QStringLiteral("TIMESTAMP WITH TIME ZONE ") + QLatin1Char('\'') + - QLocale::c().toString(field.value().toDateTime().toUTC(), QStringLiteral("yyyy-MM-ddThh:mm:ss.zzz")) + + QLocale::c().toString(field.value().toDateTime().toUTC(), u"yyyy-MM-ddThh:mm:ss.zzz") + QLatin1Char('Z') + QLatin1Char('\''); } else { r = nullStr(); @@ -1518,7 +1527,7 @@ QString QPSQLDriver::formatValue(const QSqlField &field, bool trimStrings) const case QVariant::Time: #if QT_CONFIG(datestring) if (field.value().toTime().isValid()) { - r = QLatin1Char('\'') + field.value().toTime().toString(QLatin1String("hh:mm:ss.zzz")) + QLatin1Char('\''); + r = QLatin1Char('\'') + field.value().toTime().toString(u"hh:mm:ss.zzz") + QLatin1Char('\''); } else #endif { diff --git a/src/plugins/sqldrivers/psql/qsql_psql_p.h b/src/plugins/sqldrivers/psql/qsql_psql_p.h index 99e0b5f60f..9ac1fb50d7 100644 --- a/src/plugins/sqldrivers/psql/qsql_psql_p.h +++ b/src/plugins/sqldrivers/psql/qsql_psql_p.h @@ -93,6 +93,7 @@ public: Version9_6 = 22, Version10 = 23, Version11 = 24, + Version12 = 25, UnknownLaterVersion = 100000 }; diff --git a/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp b/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp index f1a003ddcd..001bd673fc 100644 --- a/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp +++ b/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp @@ -531,7 +531,7 @@ bool QSQLiteResult::exec() } case QVariant::Time: { const QTime time = value.toTime(); - const QString str = time.toString(QStringViewLiteral("hh:mm:ss.zzz")); + const QString str = time.toString(u"hh:mm:ss.zzz"); res = sqlite3_bind_text16(d->stmt, i + 1, str.utf16(), str.size() * sizeof(ushort), SQLITE_TRANSIENT); break; diff --git a/src/plugins/sqldrivers/sqlite/qsql_sqlite_p.h b/src/plugins/sqldrivers/sqlite/qsql_sqlite_p.h index 61be4c937f..c7952bca9a 100644 --- a/src/plugins/sqldrivers/sqlite/qsql_sqlite_p.h +++ b/src/plugins/sqldrivers/sqlite/qsql_sqlite_p.h @@ -72,8 +72,8 @@ class Q_EXPORT_SQLDRIVER_SQLITE QSQLiteDriver : public QSqlDriver Q_OBJECT friend class QSQLiteResultPrivate; public: - explicit QSQLiteDriver(QObject *parent = 0); - explicit QSQLiteDriver(sqlite3 *connection, QObject *parent = 0); + explicit QSQLiteDriver(QObject *parent = nullptr); + explicit QSQLiteDriver(sqlite3 *connection, QObject *parent = nullptr); ~QSQLiteDriver(); bool hasFeature(DriverFeature f) const override; bool open(const QString & db, diff --git a/src/plugins/sqldrivers/sqlite2/qsql_sqlite2.cpp b/src/plugins/sqldrivers/sqlite2/qsql_sqlite2.cpp index 390f05c7aa..b7bcd044ab 100644 --- a/src/plugins/sqldrivers/sqlite2/qsql_sqlite2.cpp +++ b/src/plugins/sqldrivers/sqlite2/qsql_sqlite2.cpp @@ -43,7 +43,6 @@ #include <qvariant.h> #include <qdatetime.h> #include <qfile.h> -#include <qregexp.h> #include <qsqlerror.h> #include <qsqlfield.h> #include <qsqlindex.h> diff --git a/src/plugins/sqldrivers/sqlite2/smain.cpp b/src/plugins/sqldrivers/sqlite2/smain.cpp index 3a5734f8c9..7d971d6e5a 100644 --- a/src/plugins/sqldrivers/sqlite2/smain.cpp +++ b/src/plugins/sqldrivers/sqlite2/smain.cpp @@ -43,6 +43,7 @@ QT_BEGIN_NAMESPACE +// ### Qt6: remove, obsolete since 5.14 class QSQLite2DriverPlugin : public QSqlDriverPlugin { Q_OBJECT diff --git a/src/plugins/sqldrivers/tds/main.cpp b/src/plugins/sqldrivers/tds/main.cpp index 4aa1444608..18efb22ea4 100644 --- a/src/plugins/sqldrivers/tds/main.cpp +++ b/src/plugins/sqldrivers/tds/main.cpp @@ -50,6 +50,7 @@ QT_BEGIN_NAMESPACE +// ### Qt6: remove, obsolete since 4.7 class QTDSDriverPlugin : public QSqlDriverPlugin { Q_OBJECT diff --git a/src/plugins/sqldrivers/tds/qsql_tds.cpp b/src/plugins/sqldrivers/tds/qsql_tds.cpp index ad95b097ef..9c8d242028 100644 --- a/src/plugins/sqldrivers/tds/qsql_tds.cpp +++ b/src/plugins/sqldrivers/tds/qsql_tds.cpp @@ -813,7 +813,7 @@ QString QTDSDriver::formatValue(const QSqlField &field, r = QLatin1String("NULL"); else if (field.type() == QVariant::DateTime) { if (field.value().toDateTime().isValid()){ - r = field.value().toDateTime().toString(QLatin1String("yyyyMMdd hh:mm:ss")); + r = field.value().toDateTime().toString(u"yyyyMMdd hh:mm:ss"); r.prepend(QLatin1String("'")); r.append(QLatin1String("'")); } else diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm index 62f089b654..63dc49fd18 100644 --- a/src/plugins/styles/mac/qmacstyle_mac.mm +++ b/src/plugins/styles/mac/qmacstyle_mac.mm @@ -50,92 +50,30 @@ #define QMAC_QAQUASTYLE_SIZE_CONSTRAIN //#define DEBUG_SIZE_CONSTRAINT -#include <private/qcore_mac_p.h> -#if QT_CONFIG(tabbar) -#include <private/qtabbar_p.h> -#endif -#include <private/qpainter_p.h> -#include <qapplication.h> -#include <qbitmap.h> -#if QT_CONFIG(combobox) -#include <private/qcombobox_p.h> -#include <qcombobox.h> -#endif -#if QT_CONFIG(dialogbuttonbox) -#include <qdialogbuttonbox.h> -#endif -#if QT_CONFIG(dockwidget) -#include <qdockwidget.h> -#endif -#include <qevent.h> -#include <qfocusframe.h> -#include <qformlayout.h> -#include <qgroupbox.h> -#include <qhash.h> -#include <qheaderview.h> -#if QT_CONFIG(lineedit) -#include <qlineedit.h> -#endif -#if QT_CONFIG(mainwindow) -#include <qmainwindow.h> -#endif +#include <QtCore/qoperatingsystemversion.h> +#include <QtCore/qvariant.h> +#include <QtCore/qvarlengtharray.h> + +#include <QtCore/private/qcore_mac_p.h> + +#include <QtGui/private/qcoregraphics_p.h> +#include <QtGui/qpa/qplatformfontdatabase.h> +#include <QtGui/qpa/qplatformtheme.h> + +#include <QtWidgets/private/qstyleanimation_p.h> + #if QT_CONFIG(mdiarea) -#include <qmdisubwindow.h> -#endif -#if QT_CONFIG(menubar) -#include <qmenubar.h> -#endif -#include <qpaintdevice.h> -#include <qpainter.h> -#include <qpixmapcache.h> -#include <qpointer.h> -#if QT_CONFIG(progressbar) -#include <qprogressbar.h> -#endif -#if QT_CONFIG(pushbutton) -#include <qpushbutton.h> -#endif -#include <qradiobutton.h> -#if QT_CONFIG(rubberband) -#include <qrubberband.h> +#include <QtWidgets/qmdisubwindow.h> #endif #if QT_CONFIG(scrollbar) -#include <qscrollbar.h> -#endif -#if QT_CONFIG(sizegrip) -#include <qsizegrip.h> -#endif -#include <qstyleoption.h> -#include <qtoolbar.h> -#if QT_CONFIG(toolbutton) -#include <qtoolbutton.h> +#include <QtWidgets/qscrollbar.h> #endif -#if QT_CONFIG(treeview) -#include <qtreeview.h> -#endif -#if QT_CONFIG(tableview) -#include <qtableview.h> +#if QT_CONFIG(tabbar) +#include <QtWidgets/private/qtabbar_p.h> #endif -#include <qoperatingsystemversion.h> #if QT_CONFIG(wizard) -#include <qwizard.h> -#endif -#include <qdebug.h> -#if QT_CONFIG(datetimeedit) -#include <qdatetimeedit.h> +#include <QtWidgets/qwizard.h> #endif -#include <qmath.h> -#include <QtWidgets/qgraphicsproxywidget.h> -#if QT_CONFIG(graphicsview) -#include <QtWidgets/qgraphicsview.h> -#endif -#include <QtCore/qvariant.h> -#include <QtCore/qvarlengtharray.h> -#include <private/qstylehelper_p.h> -#include <private/qstyleanimation_p.h> -#include <qpa/qplatformfontdatabase.h> -#include <qpa/qplatformtheme.h> -#include <QtGui/private/qcoregraphics_p.h> #include <cmath> @@ -297,6 +235,7 @@ static QLinearGradient titlebarGradientInactive() return qt_mac_applicationIsInDarkMode() ? darkGradient : lightGradient; } +#if QT_CONFIG(tabwidget) static void clipTabBarFrame(const QStyleOption *option, const QMacStyle *style, CGContextRef ctx) { Q_ASSERT(option); @@ -316,6 +255,7 @@ static void clipTabBarFrame(const QStyleOption *option, const QMacStyle *style, CGContextClipToRects(ctx, &cgRects[0], size_t(cgRects.size())); } } +#endif static const QColor titlebarSeparatorLineActive(111, 111, 111); static const QColor titlebarSeparatorLineInactive(131, 131, 131); @@ -340,6 +280,7 @@ static const qreal titleBarButtonSpacing = 8; // hovered: tab is hovered bool isDarkMode() { return qt_mac_applicationIsInDarkMode(); } +#if QT_CONFIG(tabbar) static const QColor lightTabBarTabBackgroundActive(190, 190, 190); static const QColor darkTabBarTabBackgroundActive(38, 38, 38); static const QColor tabBarTabBackgroundActive() { return isDarkMode() ? darkTabBarTabBackgroundActive : lightTabBarTabBackgroundActive; } @@ -385,6 +326,21 @@ static const QColor tabBarCloseButtonCrossSelected(115, 115, 115); static const int closeButtonSize = 14; static const qreal closeButtonCornerRadius = 2.0; +#endif // QT_CONFIG(tabbar) + +#ifndef QT_NO_ACCESSIBILITY // This ifdef to avoid "unused function" warning. +QBrush brushForToolButton(bool isOnKeyWindow) +{ + // When a toolbutton in a toolbar is in the 'ON' state, we draw a + // partially transparent background. The colors must be different + // for 'Aqua' and 'DarkAqua' appearances though. + if (isDarkMode()) + return isOnKeyWindow ? QColor(73, 73, 73, 100) : QColor(56, 56, 56, 100); + + return isOnKeyWindow ? QColor(0, 0, 0, 28) : QColor(0, 0, 0, 21); +} +#endif // QT_NO_ACCESSIBILITY + static const int headerSectionArrowHeight = 6; static const int headerSectionSeparatorInset = 2; @@ -560,6 +516,7 @@ static bool isInMacUnifiedToolbarArea(QWindow *window, int windowY) } +#if QT_CONFIG(tabbar) static void drawTabCloseButton(QPainter *p, bool hover, bool selected, bool pressed, bool documentMode) { p->setRenderHints(QPainter::Antialiasing); @@ -597,7 +554,6 @@ static void drawTabCloseButton(QPainter *p, bool hover, bool selected, bool pres p->drawLine(margin, height - margin, width - margin, margin); } -#if QT_CONFIG(tabbar) QRect rotateTabPainter(QPainter *p, QTabBar::Shape shape, QRect tabRect) { const auto tabDirection = QMacStylePrivate::tabDirection(shape); @@ -613,10 +569,10 @@ QRect rotateTabPainter(QPainter *p, QTabBar::Shape shape, QRect tabRect) newRot = -90; } tabRect.setRect(0, 0, tabRect.height(), tabRect.width()); - QMatrix m; - m.translate(newX, newY); - m.rotate(newRot); - p->setMatrix(m, true); + QTransform transform; + transform.translate(newX, newY); + transform.rotate(newRot); + p->setTransform(transform, true); } return tabRect; } @@ -919,8 +875,10 @@ static QSize qt_aqua_get_known_size(QStyle::ContentsType ct, const QWidget *widg else if (qobject_cast<const QLineEdit *>(widg)) ct = QStyle::CT_LineEdit; #endif +#if QT_CONFIG(itemviews) else if (qobject_cast<const QHeaderView *>(widg)) ct = QStyle::CT_HeaderSection; +#endif #if QT_CONFIG(menubar) else if (qobject_cast<const QMenuBar *>(widg)) ct = QStyle::CT_MenuBar; @@ -2221,10 +2179,12 @@ int QMacStyle::pixelMetric(PixelMetric metric, const QStyleOption *opt, const QW int ret = 0; switch (metric) { +#if QT_CONFIG(tabbar) case PM_TabCloseIndicatorWidth: case PM_TabCloseIndicatorHeight: ret = closeButtonSize; break; +#endif case PM_ToolBarIconSize: ret = proxy()->pixelMetric(PM_LargeIconSize); break; @@ -2348,11 +2308,11 @@ int QMacStyle::pixelMetric(PixelMetric metric, const QStyleOption *opt, const QW } break; case PM_SmallIconSize: - ret = int(QStyleHelper::dpiScaled(16.)); + ret = int(QStyleHelper::dpiScaled(16., opt)); break; case PM_LargeIconSize: - ret = int(QStyleHelper::dpiScaled(32.)); + ret = int(QStyleHelper::dpiScaled(32., opt)); break; case PM_IconViewIconSize: @@ -2381,10 +2341,12 @@ int QMacStyle::pixelMetric(PixelMetric metric, const QStyleOption *opt, const QW ret = 16; break; case QStyleHelper::SizeDefault: +#if QT_CONFIG(tabbar) const QStyleOptionTab *tb = qstyleoption_cast<const QStyleOptionTab *>(opt); if (tb && tb->documentMode) ret = 30; else +#endif ret = QCommonStyle::pixelMetric(metric, opt, widget); break; } @@ -2895,9 +2857,11 @@ int QMacStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *w ret = [NSScroller preferredScrollerStyle] == NSScrollerStyleOverlay; } break; +#if QT_CONFIG(itemviews) case SH_ItemView_ScrollMode: ret = QAbstractItemView::ScrollPerPixel; break; +#endif case SH_TitleBar_ShowToolTipsOnButtons: // min/max/close buttons on windows don't show tool tips ret = false; @@ -3001,24 +2965,24 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai } #endif - QMatrix matrix; - matrix.translate(opt->rect.center().x() + xOffset, opt->rect.center().y() + 2); + QTransform transform; + transform.translate(opt->rect.center().x() + xOffset, opt->rect.center().y() + 2); QPainterPath path; switch(pe) { default: case PE_IndicatorArrowDown: break; case PE_IndicatorArrowUp: - matrix.rotate(180); + transform.rotate(180); break; case PE_IndicatorArrowLeft: - matrix.rotate(90); + transform.rotate(90); break; case PE_IndicatorArrowRight: - matrix.rotate(-90); + transform.rotate(-90); break; } - p->setMatrix(matrix); + p->setTransform(transform); path.moveTo(-halfSize, -halfSize * 0.5); path.lineTo(0.0, halfSize * 0.5); @@ -3039,7 +3003,7 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai p->restore(); return; } - +#if QT_CONFIG(tabwidget) QRegion region(tbb->rect); region -= tbb->tabBarRect; p->save(); @@ -3063,6 +3027,7 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai } proxy()->drawPrimitive(PE_FrameTabWidget, &twf, p, w); p->restore(); +#endif } break; #endif @@ -3109,8 +3074,10 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai needTranslation = true; } d->drawNSViewInRect(box, adjustedRect, p, ^(CGContextRef ctx, const CGRect &rect) { +#if QT_CONFIG(tabwidget) if (QTabWidget *tabWidget = qobject_cast<QTabWidget *>(opt->styleObject)) clipTabBarFrame(opt, this, ctx); +#endif CGContextTranslateCTM(ctx, 0, rect.origin.y + rect.size.height); CGContextScaleCTM(ctx, 1, -1); if (QOperatingSystemVersion::current() < QOperatingSystemVersion::MacOSMojave @@ -3404,6 +3371,7 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai } break; case PE_FrameStatusBarItem: break; +#if QT_CONFIG(tabbar) case PE_IndicatorTabClose: { // Make close button visible only on the hovered tab. QTabBar *tabBar = qobject_cast<QTabBar*>(w->parentWidget()); @@ -3428,6 +3396,7 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai } } } break; +#endif // QT_CONFIG(tabbar) case PE_PanelStatusBar: { // Fill the status bar with the titlebar gradient. QLinearGradient linearGrad; @@ -3507,6 +3476,7 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter { Q_D(const QMacStyle); const AppearanceSync sync; + const QMacAutoReleasePool pool; QMacCGContext cg(p); QWindow *window = w && w->window() ? w->window()->windowHandle() : nullptr; d->resolveCurrentNSView(window); @@ -4371,7 +4341,6 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter break; case CE_ProgressBarContents: if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) { - QMacAutoReleasePool pool; const bool isIndeterminate = (pb->minimum == 0 && pb->maximum == 0); const bool vertical = pb->orientation == Qt::Vertical; const bool inverted = pb->invertedAppearance; @@ -4598,6 +4567,7 @@ QRect QMacStyle::subElementRect(SubElement sr, const QStyleOption *opt, const int controlSize = getControlSize(opt, widget); switch (sr) { +#if QT_CONFIG(itemviews) case SE_ItemViewItemText: if (const QStyleOptionViewItem *vopt = qstyleoption_cast<const QStyleOptionViewItem *>(opt)) { int fw = proxy()->pixelMetric(PM_FocusFrameHMargin, opt, widget); @@ -4607,6 +4577,7 @@ QRect QMacStyle::subElementRect(SubElement sr, const QStyleOption *opt, rect.adjust(-fw, 0, 0, 0); } break; +#endif case SE_ToolBoxTabContents: rect = QCommonStyle::subElementRect(sr, opt, widget); break; @@ -5317,9 +5288,20 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex } d->drawNSViewInRect(slider, opt->rect, p, ^(CGContextRef ctx, const CGRect &rect) { - if (isHorizontal && sl->upsideDown) { - CGContextTranslateCTM(ctx, rect.size.width, 0); - CGContextScaleCTM(ctx, -1, 1); + + // Since the GC is flipped, upsideDown means *not* inverted when vertical. + const bool verticalFlip = !isHorizontal && !sl->upsideDown; // FIXME: && !isSierraOrLater + + if (isHorizontal) { + if (sl->upsideDown) { + CGContextTranslateCTM(ctx, rect.size.width, rect.origin.y); + CGContextScaleCTM(ctx, -1, 1); + } else { + CGContextTranslateCTM(ctx, 0, rect.origin.y); + } + } else if (verticalFlip) { + CGContextTranslateCTM(ctx, rect.origin.x, rect.size.height); + CGContextScaleCTM(ctx, 1, -1); } if (hasDoubleTicks) { @@ -5330,9 +5312,6 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex CGContextTranslateCTM(ctx, 1, 0); } - // Since the GC is flipped, upsideDown means *not* inverted when vertical. - const bool verticalFlip = !isHorizontal && !sl->upsideDown; // FIXME: && !isSierraOrLater - #if 0 // FIXME: Sadly, this part doesn't work. It seems to somehow polute the // NSSlider's internal state and, when we need to use the "else" part, @@ -5396,9 +5375,6 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex // This ain't HIG kosher: force round knob look. if (hasDoubleTicks) slider.numberOfTickMarks = 0; - // Draw the knob in the symmetrical position instead of flipping. - if (verticalFlip) - slider.intValue = slider.maxValue - slider.intValue + slider.minValue; [cell drawKnob]; } } @@ -5641,8 +5617,7 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex if (view) isKey = [view.window isKeyWindow]; - QBrush brush(isKey ? QColor(0, 0, 0, 28) - : QColor(0, 0, 0, 21)); + QBrush brush(brushForToolButton(isKey)); QPainterPath path; path.addRoundedRect(QRectF(tb->rect.x(), tb->rect.y(), tb->rect.width(), tb->rect.height() + 4), 4, 4); p->setRenderHint(QPainter::Antialiasing); @@ -6436,12 +6411,14 @@ QSize QMacStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt, sz = sz.expandedTo(QSize(sz.width(), minimumSize)); } break; +#if QT_CONFIG(itemviews) case CT_ItemViewItem: if (const QStyleOptionViewItem *vopt = qstyleoption_cast<const QStyleOptionViewItem *>(opt)) { sz = QCommonStyle::sizeFromContents(ct, vopt, csz, widget); sz.setHeight(sz.height() + 2); } break; +#endif default: sz = QCommonStyle::sizeFromContents(ct, opt, csz, widget); diff --git a/src/plugins/styles/mac/qmacstyle_mac_p_p.h b/src/plugins/styles/mac/qmacstyle_mac_p_p.h index 6b3f525adc..d6af18f01f 100644 --- a/src/plugins/styles/mac/qmacstyle_mac_p_p.h +++ b/src/plugins/styles/mac/qmacstyle_mac_p_p.h @@ -41,98 +41,105 @@ #ifndef QMACSTYLE_MAC_P_P_H #define QMACSTYLE_MAC_P_P_H -#include <QtWidgets/private/qtwidgetsglobal_p.h> -#include <QtWidgets/private/qcommonstyle_p.h> #include "qmacstyle_mac_p.h" -#include <private/qapplication_p.h> + +#include <QtCore/qdebug.h> +#include <QtCore/qhash.h> +#include <QtCore/qmap.h> +#include <QtCore/qmath.h> +#include <QtCore/qpair.h> +#include <QtCore/qpointer.h> +#include <QtCore/qtextstream.h> +#include <QtCore/qvector.h> + +#include <QtGui/private/qpainter_p.h> + +#include <QtGui/qbitmap.h> +#include <QtGui/qevent.h> +#include <QtGui/qpaintdevice.h> +#include <QtGui/qpainter.h> +#include <QtGui/qpixmapcache.h> + +#include <QtWidgets/private/qapplication_p.h> +#include <QtWidgets/private/qcommonstyle_p.h> +#include <QtWidgets/private/qstylehelper_p.h> + +#include <QtWidgets/qapplication.h> +#include <QtWidgets/qfocusframe.h> +#include <QtWidgets/qformlayout.h> +#include <QtWidgets/qlayout.h> +#include <QtWidgets/qstyleoption.h> +#include <QtWidgets/qtextedit.h> + +#if QT_CONFIG(checkbox) +#include <QtWidgets/qcheckbox.h> +#endif #if QT_CONFIG(combobox) -#include <private/qcombobox_p.h> +#include <QtWidgets/private/qcombobox_p.h> +#include <QtWidgets/qcombobox.h> #endif -#include <private/qpainter_p.h> -#include <private/qstylehelper_p.h> -#include <qapplication.h> -#include <qbitmap.h> -#if QT_CONFIG(checkbox) -#include <qcheckbox.h> +#if QT_CONFIG(datetimeedit) +#include <QtWidgets/qdatetimeedit.h> #endif -#include <qcombobox.h> #if QT_CONFIG(dialogbuttonbox) -#include <qdialogbuttonbox.h> +#include <QtWidgets/qdialogbuttonbox.h> #endif #if QT_CONFIG(dockwidget) -#include <qdockwidget.h> +#include <QtWidgets/qdockwidget.h> +#endif +#if QT_CONFIG(graphicsview) +#include <QtWidgets/qgraphicsproxywidget.h> +#include <QtWidgets/qgraphicsview.h> #endif -#include <qevent.h> -#include <qfocusframe.h> -#include <qformlayout.h> #if QT_CONFIG(groupbox) -#include <qgroupbox.h> +#include <QtWidgets/qgroupbox.h> +#endif +#if QT_CONFIG(itemviews) +#include <QtWidgets/qheaderview.h> #endif -#include <qhash.h> -#include <qheaderview.h> -#include <qlayout.h> #if QT_CONFIG(lineedit) -#include <qlineedit.h> +#include <QtWidgets/qlineedit.h> #endif #if QT_CONFIG(listview) -#include <qlistview.h> +#include <QtWidgets/qlistview.h> #endif #if QT_CONFIG(mainwindow) -#include <qmainwindow.h> +#include <QtWidgets/qmainwindow.h> #endif -#include <qmap.h> #if QT_CONFIG(menubar) -#include <qmenubar.h> +#include <QtWidgets/qmenubar.h> #endif -#include <qpaintdevice.h> -#include <qpainter.h> -#include <qpixmapcache.h> -#include <qpointer.h> #if QT_CONFIG(progressbar) -#include <qprogressbar.h> +#include <QtWidgets/qprogressbar.h> #endif #if QT_CONFIG(pushbutton) -#include <qpushbutton.h> +#include <QtWidgets/qpushbutton.h> #endif -#include <qradiobutton.h> +#include <QtWidgets/qradiobutton.h> #if QT_CONFIG(rubberband) -#include <qrubberband.h> +#include <QtWidgets/qrubberband.h> #endif #if QT_CONFIG(sizegrip) -#include <qsizegrip.h> +#include <QtWidgets/qsizegrip.h> #endif #if QT_CONFIG(spinbox) -#include <qspinbox.h> +#include <QtWidgets/qspinbox.h> #endif #if QT_CONFIG(splitter) -#include <qsplitter.h> +#include <QtWidgets/qsplitter.h> +#endif +#if QT_CONFIG(tableview) +#include <QtWidgets/qtableview.h> #endif -#include <qstyleoption.h> -#include <qtextedit.h> -#include <qtextstream.h> #if QT_CONFIG(toolbar) -#include <qtoolbar.h> +#include <QtWidgets/qtoolbar.h> #endif #if QT_CONFIG(toolbutton) -#include <qtoolbutton.h> +#include <QtWidgets/qtoolbutton.h> #endif #if QT_CONFIG(treeview) -#include <qtreeview.h> -#endif -#if QT_CONFIG(tableview) -#include <qtableview.h> +#include <QtWidgets/qtreeview.h> #endif -#include <qdebug.h> -#if QT_CONFIG(datetimeedit) -#include <qdatetimeedit.h> -#endif -#include <qmath.h> -#include <qpair.h> -#include <qvector.h> -#include <QtWidgets/qgraphicsproxywidget.h> -#include <QtWidgets/qgraphicsview.h> - - // // W A R N I N G diff --git a/src/plugins/styles/windowsvista/main.cpp b/src/plugins/styles/windowsvista/main.cpp index d5048e45b7..5e7bcf5e6e 100644 --- a/src/plugins/styles/windowsvista/main.cpp +++ b/src/plugins/styles/windowsvista/main.cpp @@ -48,7 +48,7 @@ class QWindowsVistaStylePlugin : public QStylePlugin Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QStyleFactoryInterface" FILE "windowsvistastyle.json") public: - QStyle *create(const QString &key); + QStyle *create(const QString &key) override; }; QStyle *QWindowsVistaStylePlugin::create(const QString &key) @@ -56,7 +56,7 @@ QStyle *QWindowsVistaStylePlugin::create(const QString &key) if (key.compare(QLatin1String("windowsvista"), Qt::CaseInsensitive) == 0) return new QWindowsVistaStyle(); - return 0; + return nullptr; } QT_END_NAMESPACE diff --git a/src/plugins/styles/windowsvista/qwindowsvistastyle.cpp b/src/plugins/styles/windowsvista/qwindowsvistastyle.cpp index 8a3ae17b1d..e213d65946 100644 --- a/src/plugins/styles/windowsvista/qwindowsvistastyle.cpp +++ b/src/plugins/styles/windowsvista/qwindowsvistastyle.cpp @@ -44,7 +44,6 @@ #include <qwindow.h> #include <private/qstyleanimation_p.h> #include <private/qstylehelper_p.h> -#include <private/qapplication_p.h> #include <qpa/qplatformnativeinterface.h> QT_BEGIN_NAMESPACE @@ -84,16 +83,14 @@ static const int windowsRightBorder = 15; // right border on windows */ bool QWindowsVistaStylePrivate::useVista() { - return (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA - && (QSysInfo::WindowsVersion & QSysInfo::WV_NT_based)) - && QWindowsVistaStylePrivate::useXP(); + return QWindowsVistaStylePrivate::useXP(); } /* \internal Checks and returns the style object */ inline QObject *styleObject(const QStyleOption *option) { - return option ? option->styleObject : 0; + return option ? option->styleObject : nullptr; } /* \internal @@ -118,7 +115,7 @@ static inline QImage createAnimationBuffer(const QStyleOption *option, const QWi Used by animations to clone a styleoption and shift its offset */ QStyleOption *clonedAnimationStyleOption(const QStyleOption*option) { - QStyleOption *styleOption = 0; + QStyleOption *styleOption = nullptr; if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider*>(option)) styleOption = new QStyleOptionSlider(*slider); else if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox*>(option)) @@ -299,7 +296,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt int oldState = styleObject->property("_q_stylestate").toInt(); oldRect = styleObject->property("_q_stylerect").toRect(); newRect = option->rect; - styleObject->setProperty("_q_stylestate", (int)option->state); + styleObject->setProperty("_q_stylestate", int(option->state)); styleObject->setProperty("_q_stylerect", option->rect); bool doTransition = oldState && @@ -317,7 +314,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt if (doTransition) { QStyleOption *styleOption = clonedAnimationStyleOption(option); - styleOption->state = (QStyle::State)oldState; + styleOption->state = QStyle::State(oldState); QWindowsVistaAnimation *anim = qobject_cast<QWindowsVistaAnimation *>(d->animation(styleObject)); QWindowsVistaTransition *t = new QWindowsVistaTransition(styleObject); @@ -342,7 +339,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt // The end state of the transition is simply the result we would have painted // if the style was not animated. - styleOption->styleObject = 0; + styleOption->styleObject = nullptr; styleOption->state = option->state; proxy()->drawPrimitive(element, styleOption, &endPainter, widget); @@ -357,7 +354,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt //translate state flags to UXTHEME states : if (element == PE_FrameLineEdit) { - theme = OpenThemeData(0, L"Edit"); + theme = OpenThemeData(nullptr, L"Edit"); partId = EP_EDITBORDER_NOSCROLL; if (oldState & State_MouseOver) @@ -375,7 +372,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt toState = ETS_NORMAL; } else { - theme = OpenThemeData(0, L"Button"); + theme = OpenThemeData(nullptr, L"Button"); if (element == PE_IndicatorRadioButton) partId = BP_RADIOBUTTON; else if (element == PE_IndicatorCheckBox) @@ -391,7 +388,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt if (theme && SUCCEEDED(GetThemeTransitionDuration(theme, partId, fromState, toState, TMT_TRANSITIONDURATIONS, &duration))) { - t->setDuration(duration); + t->setDuration(int(duration)); } t->setStartTime(QTime::currentTime()); @@ -536,7 +533,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt else if (state & State_MouseOver) stateId = EBS_HOT; - XPThemeData theme(0, painter, QWindowsXPStylePrivate::EditTheme, + XPThemeData theme(nullptr, painter, QWindowsXPStylePrivate::EditTheme, partId, stateId, rect); if (!theme.isValid()) { QWindowsStyle::drawPrimitive(element, option, painter, widget); @@ -583,27 +580,26 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt p->drawRect(option->rect.adjusted(0, 0, -1, -1)); p->setPen(oldPen); return; - } else { - int stateId = ETS_NORMAL; - if (!(state & State_Enabled)) - stateId = ETS_DISABLED; - else if (state & State_ReadOnly) - stateId = ETS_READONLY; - else if (state & State_MouseOver) - stateId = ETS_HOT; - else if (state & State_HasFocus) - stateId = ETS_SELECTED; - XPThemeData theme(widget, painter, - QWindowsXPStylePrivate::EditTheme, - EP_EDITBORDER_NOSCROLL, stateId, option->rect); - theme.noContent = true; - painter->save(); - QRegion clipRegion = option->rect; - clipRegion -= option->rect.adjusted(2, 2, -2, -2); - painter->setClipRegion(clipRegion); - d->drawBackground(theme); - painter->restore(); } + int stateId = ETS_NORMAL; + if (!(state & State_Enabled)) + stateId = ETS_DISABLED; + else if (state & State_ReadOnly) + stateId = ETS_READONLY; + else if (state & State_MouseOver) + stateId = ETS_HOT; + else if (state & State_HasFocus) + stateId = ETS_SELECTED; + XPThemeData theme(widget, painter, + QWindowsXPStylePrivate::EditTheme, + EP_EDITBORDER_NOSCROLL, stateId, option->rect); + theme.noContent = true; + painter->save(); + QRegion clipRegion = option->rect; + clipRegion -= option->rect.adjusted(2, 2, -2, -2); + painter->setClipRegion(clipRegion); + d->drawBackground(theme); + painter->restore(); } break; @@ -726,7 +722,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt d->drawBackground(theme); } else { QWindowsXPStyle::drawPrimitive(PE_PanelItemViewItem, option, painter, widget); - break;; + break; } QPixmapCache::insert(key, pixmap); } @@ -772,7 +768,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt case PE_Widget: { #if QT_CONFIG(dialogbuttonbox) - const QDialogButtonBox *buttonBox = 0; + const QDialogButtonBox *buttonBox = nullptr; if (qobject_cast<const QMessageBox *> (widget)) buttonBox = widget->findChild<const QDialogButtonBox *>(QLatin1String("qt_msgbox_buttonbox")); @@ -846,7 +842,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption int oldState = styleObject->property("_q_stylestate").toInt(); oldRect = styleObject->property("_q_stylerect").toRect(); newRect = option->rect; - styleObject->setProperty("_q_stylestate", (int)option->state); + styleObject->setProperty("_q_stylestate", int(option->state)); styleObject->setProperty("_q_stylerect", option->rect); bool wasDefault = false; @@ -872,7 +868,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption QWindowsVistaTransition *t = new QWindowsVistaTransition(styleObject); QWindowsVistaAnimation *anim = qobject_cast<QWindowsVistaAnimation *>(d->animation(styleObject)); QStyleOption *styleOption = clonedAnimationStyleOption(option); - styleOption->state = (QStyle::State)oldState; + styleOption->state = QStyle::State(oldState); QImage startImage = createAnimationBuffer(option, widget); QPainter startPainter(&startImage); @@ -894,12 +890,12 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption DWORD duration = 0; - const HTHEME theme = OpenThemeData(0, L"Button"); + const HTHEME theme = OpenThemeData(nullptr, L"Button"); int fromState = buttonStateId(oldState, BP_PUSHBUTTON); int toState = buttonStateId(option->state, BP_PUSHBUTTON); if (GetThemeTransitionDuration(theme, BP_PUSHBUTTON, fromState, toState, TMT_TRANSITIONDURATIONS, &duration) == S_OK) - t->setDuration(duration); + t->setDuration(int(duration)); else t->setDuration(0); t->setStartTime(QTime::currentTime()); @@ -985,16 +981,16 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption if (btn->features & QStyleOptionButton::HasMenu) { int mbiw = 0, mbih = 0; - XPThemeData theme(widget, 0, QWindowsXPStylePrivate::ToolBarTheme, + XPThemeData theme(widget, nullptr, QWindowsXPStylePrivate::ToolBarTheme, TP_DROPDOWNBUTTON); if (theme.isValid()) { - const QSizeF size = theme.size() * QStyleHelper::dpiScaled(1); + const QSizeF size = theme.size() * QStyleHelper::dpiScaled(1, option); if (!size.isEmpty()) { mbiw = qRound(size.width()); mbih = qRound(size.height()); } } - QRect ir = subElementRect(SE_PushButtonContents, option, 0); + QRect ir = subElementRect(SE_PushButtonContents, option, nullptr); QStyleOptionButton newBtn = *btn; newBtn.rect = QStyle::visualRect(option->direction, option->rect, QRect(ir.right() - mbiw - 2, @@ -1139,7 +1135,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption QPalette::ColorRole textRole = disabled ? QPalette::Text : QPalette::ButtonText; QPixmap pix = mbi->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option, widget), QIcon::Normal); - uint alignment = Qt::AlignCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine; + int alignment = Qt::AlignCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine; if (!proxy()->styleHint(SH_UnderlineShortcut, mbi, widget)) alignment |= Qt::TextHideMnemonic; @@ -1179,7 +1175,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption int checkcol = qRound(qreal(25) * factor); const int gutterWidth = qRound(qreal(3) * factor); { - XPThemeData theme(widget, 0, QWindowsXPStylePrivate::MenuTheme, + XPThemeData theme(widget, nullptr, QWindowsXPStylePrivate::MenuTheme, MENU_POPUPCHECKBACKGROUND, MBI_HOT); XPThemeData themeSize = theme; themeSize.partId = MENU_POPUPCHECK; @@ -1396,7 +1392,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption int mw = proxy()->pixelMetric(QStyle::PM_DockWidgetTitleMargin, dwOpt, widget); int fw = proxy()->pixelMetric(PM_DockWidgetFrameWidth, dwOpt, widget); const QDockWidget *dw = qobject_cast<const QDockWidget *>(widget); - bool isFloating = dw != 0 && dw->isFloating(); + bool isFloating = dw && dw->isFloating(); QRect r = option->rect.adjusted(0, 2, -1, -3); QRect titleRect = r; @@ -1413,7 +1409,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption if (isFloating) { titleRect.adjust(0, -fw, 0, 0); - if (widget != 0 && widget->windowIcon().cacheKey() != QApplication::windowIcon().cacheKey()) + if (widget && widget->windowIcon().cacheKey() != QApplication::windowIcon().cacheKey()) titleRect.adjust(titleRect.height() + mw, 0, 0, 0); } else { titleRect.adjust(mw, 0, 0, 0); @@ -1519,8 +1515,8 @@ void QWindowsVistaStyle::drawComplexControl(ComplexControl control, const QStyle int oldActiveControls = styleObject->property("_q_stylecontrols").toInt(); QRect oldRect = styleObject->property("_q_stylerect").toRect(); - styleObject->setProperty("_q_stylestate", (int)option->state); - styleObject->setProperty("_q_stylecontrols", (int)option->activeSubControls); + styleObject->setProperty("_q_stylestate", int(option->state)); + styleObject->setProperty("_q_stylecontrols", int(option->activeSubControls)); styleObject->setProperty("_q_stylerect", option->rect); bool doTransition = ((state & State_Sunken) != (oldState & State_Sunken) || @@ -1564,8 +1560,8 @@ void QWindowsVistaStyle::drawComplexControl(ComplexControl control, const QStyle // Draw transition source if (!anim) { - styleOption->state = (QStyle::State)oldState; - styleOption->activeSubControls = (QStyle::SubControl)oldActiveControls; + styleOption->state = QStyle::State(oldState); + styleOption->activeSubControls = QStyle::SubControl(oldActiveControls); proxy()->drawComplexControl(control, styleOption, &startPainter, widget); } else { anim->paint(&startPainter, option); @@ -1816,7 +1812,7 @@ void QWindowsVistaStyle::drawComplexControl(ComplexControl control, const QStyle // That however breaks with QtQuickControls where this results in transparent // spinbox background, so if there's no "widget" passed (QtQuickControls case), // let ftheme.noContent be false, which fixes the spinbox rendering in QQC - ftheme.noContent = (widget != NULL); + ftheme.noContent = (widget != nullptr); d->drawBackground(ftheme); } if (sub & SC_SpinBoxUp) { @@ -1873,7 +1869,7 @@ QSize QWindowsVistaStyle::sizeFromContents(ContentsType type, const QStyleOption sz = QWindowsXPStyle::sizeFromContents(type, option, size, widget); int minimumHeight; { - XPThemeData theme(widget, 0, + XPThemeData theme(widget, nullptr, QWindowsXPStylePrivate::MenuTheme, MENU_POPUPCHECKBACKGROUND, MBI_HOT); XPThemeData themeSize = theme; @@ -1941,7 +1937,7 @@ QRect QWindowsVistaStyle::subElementRect(SubElement element, const QStyleOption case SE_PushButtonContents: if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) { MARGINS borderSize; - const HTHEME theme = OpenThemeData(widget ? QWindowsVistaStylePrivate::winId(widget) : 0, L"Button"); + const HTHEME theme = OpenThemeData(widget ? QWindowsVistaStylePrivate::winId(widget) : nullptr, L"Button"); if (theme) { int stateId = PBS_NORMAL; if (!(option->state & State_Enabled)) @@ -1956,7 +1952,7 @@ QRect QWindowsVistaStyle::subElementRect(SubElement element, const QStyleOption int border = proxy()->pixelMetric(PM_DefaultFrameWidth, btn, widget); rect = option->rect.adjusted(border, border, -border, -border); - if (SUCCEEDED(GetThemeMargins(theme, NULL, BP_PUSHBUTTON, stateId, TMT_CONTENTMARGINS, NULL, &borderSize))) { + if (SUCCEEDED(GetThemeMargins(theme, nullptr, BP_PUSHBUTTON, stateId, TMT_CONTENTMARGINS, nullptr, &borderSize))) { rect.adjust(borderSize.cxLeftWidth, borderSize.cyTopHeight, -borderSize.cxRightWidth, -borderSize.cyBottomHeight); rect = visualRect(option->direction, option->rect, rect); @@ -1974,7 +1970,7 @@ QRect QWindowsVistaStyle::subElementRect(SubElement element, const QStyleOption int y = option->rect.y(); int margin = proxy()->pixelMetric(QStyle::PM_HeaderMargin, option, widget); - XPThemeData theme(widget, 0, + XPThemeData theme(widget, nullptr, QWindowsXPStylePrivate::HeaderTheme, HP_HEADERSORTARROW, HSAS_SORTEDDOWN, option->rect); @@ -2047,7 +2043,7 @@ static bool buttonVisible(const QStyle::SubControl sc, const QStyleOptionTitleBa bool isMinimized = tb->titleBarState & Qt::WindowMinimized; bool isMaximized = tb->titleBarState & Qt::WindowMaximized; - const uint flags = tb->titleBarFlags; + const auto flags = tb->titleBarFlags; bool retVal = false; switch (sc) { case QStyle::SC_TitleBarContextHelpButton: @@ -2105,7 +2101,7 @@ int QWindowsVistaStyle::styleHint(StyleHint hint, const QStyleOption *option, co if (option) { if (QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask*>(returnData)) { ret = true; - XPThemeData themeData(widget, 0, + XPThemeData themeData(widget, nullptr, QWindowsXPStylePrivate::ToolTipTheme, TTP_STANDARD, TTSS_NORMAL, option->rect); mask->region = d->region(themeData); @@ -2114,7 +2110,7 @@ int QWindowsVistaStyle::styleHint(StyleHint hint, const QStyleOption *option, co break; case SH_Table_GridLineColor: if (option) - ret = option->palette.color(QPalette::Base).darker(118).rgb(); + ret = int(option->palette.color(QPalette::Base).darker(118).rgb()); else ret = -1; break; @@ -2146,7 +2142,7 @@ QRect QWindowsVistaStyle::subControlRect(ComplexControl control, const QStyleOpt const int x = cb->rect.x(), y = cb->rect.y(), wi = cb->rect.width(), he = cb->rect.height(); const int margin = cb->frame ? 3 : 0; const int bmarg = cb->frame ? 2 : 0; - const int arrowWidth = qRound(QStyleHelper::dpiScaled(16)); + const int arrowWidth = qRound(QStyleHelper::dpiScaled(16, option)); const int arrowButtonWidth = bmarg + arrowWidth; const int xpos = x + wi - arrowButtonWidth; @@ -2180,7 +2176,7 @@ QRect QWindowsVistaStyle::subControlRect(ComplexControl control, const QStyleOpt const int height = tb->rect.height(); const int width = tb->rect.width(); const int buttonWidth = - qRound(qreal(GetSystemMetrics(SM_CXSIZE)) * factor - QStyleHelper::dpiScaled(4)); + qRound(qreal(GetSystemMetrics(SM_CXSIZE)) * factor - QStyleHelper::dpiScaled(4, option)); const int frameWidth = proxy()->pixelMetric(PM_MdiSubWindowFrameWidth, option, widget); const bool sysmenuHint = (tb->titleBarFlags & Qt::WindowSystemMenuHint) != 0; @@ -2281,7 +2277,7 @@ int QWindowsVistaStyle::pixelMetric(PixelMetric metric, const QStyleOption *opti int ret = QWindowsVistaStylePrivate::fixedPixelMetric(metric); if (ret != QWindowsStylePrivate::InvalidMetric) - return int(QStyleHelper::dpiScaled(ret)); + return int(QStyleHelper::dpiScaled(ret, option)); return QWindowsXPStyle::pixelMetric(metric, option, widget); } @@ -2325,7 +2321,7 @@ void QWindowsVistaStyle::polish(QWidget *widget) //we do not have to care about unpolishing widget->setContentsMargins(3, 0, 4, 0); COLORREF bgRef; - HTHEME theme = OpenThemeData(widget ? QWindowsVistaStylePrivate::winId(widget) : 0, L"TOOLTIP"); + HTHEME theme = OpenThemeData(widget ? QWindowsVistaStylePrivate::winId(widget) : nullptr, L"TOOLTIP"); if (theme && SUCCEEDED(GetThemeColor(theme, TTP_STANDARD, TTSS_NORMAL, TMT_TEXTCOLOR, &bgRef))) { QColor textColor = QColor::fromRgb(bgRef); QPalette pal; @@ -2465,7 +2461,7 @@ QIcon QWindowsVistaStyle::standardIcon(StandardPixmap standardIcon, switch(standardIcon) { case SP_CommandLink: { - XPThemeData theme(0, 0, + XPThemeData theme(nullptr, nullptr, QWindowsXPStylePrivate::ButtonTheme, BP_COMMANDLINKGLYPH, CMDLGS_NORMAL); if (theme.isValid()) { diff --git a/src/plugins/styles/windowsvista/qwindowsvistastyle_p_p.h b/src/plugins/styles/windowsvista/qwindowsvistastyle_p_p.h index d66b17e9f8..8fef9f9927 100644 --- a/src/plugins/styles/windowsvista/qwindowsvistastyle_p_p.h +++ b/src/plugins/styles/windowsvista/qwindowsvistastyle_p_p.h @@ -162,7 +162,7 @@ class QWindowsVistaAnimation : public QBlendStyleAnimation public: QWindowsVistaAnimation(Type type, QObject *target) : QBlendStyleAnimation(type, target) { } - virtual bool isUpdateNeeded() const; + bool isUpdateNeeded() const override; void paint(QPainter *painter, const QStyleOption *option); }; diff --git a/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp b/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp index 90026e5bf0..bf80138b32 100644 --- a/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp +++ b/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp @@ -117,7 +117,7 @@ static inline QBackingStore *backingStoreForWidget(const QWidget *widget) if (const QWidget *topLevel = widget->nativeParentWidget()) if (QBackingStore *topLevelBackingStore = topLevel->backingStore()) return topLevelBackingStore; - return 0; + return nullptr; } static inline HDC hdcForWidgetBackingStore(const QWidget *widget) @@ -127,7 +127,7 @@ static inline HDC hdcForWidgetBackingStore(const QWidget *widget) if (nativeInterface) return static_cast<HDC>(nativeInterface->nativeResourceForBackingStore(QByteArrayLiteral("getDC"), backingStore)); } - return 0; + return nullptr; } // Theme data helper ------------------------------------------------------------------------------ @@ -148,7 +148,7 @@ bool XPThemeData::isValid() HTHEME XPThemeData::handle() { if (!QWindowsXPStylePrivate::useXP()) - return 0; + return nullptr; if (!htheme) htheme = QWindowsXPStylePrivate::createTheme(theme, QWindowsXPStylePrivate::winId(widget)); @@ -175,10 +175,10 @@ RECT XPThemeData::toRECT(const QRect &qr) HRGN XPThemeData::mask(QWidget *widget) { if (!IsThemeBackgroundPartiallyTransparent(handle(), partId, stateId)) - return 0; + return nullptr; HRGN hrgn; - HDC dc = 0; + HDC dc = nullptr; if (widget) dc = hdcForWidgetBackingStore(widget); RECT nativeRect = toRECT(rect); @@ -188,7 +188,7 @@ HRGN XPThemeData::mask(QWidget *widget) // QWindowsXPStylePrivate ------------------------------------------------------------------------- // Static initializations -HWND QWindowsXPStylePrivate::m_vistaTreeViewHelper = 0; +HWND QWindowsXPStylePrivate::m_vistaTreeViewHelper = nullptr; HTHEME QWindowsXPStylePrivate::m_themes[NThemes]; bool QWindowsXPStylePrivate::use_xp = false; QBasicAtomicInt QWindowsXPStylePrivate::ref = Q_BASIC_ATOMIC_INITIALIZER(-1); // -1 based refcounting @@ -227,7 +227,7 @@ bool QWindowsXPStylePrivate::useXP(bool update) { if (!update) return use_xp; - return use_xp = IsThemeActive() && (IsAppThemed() || !QApplication::instance()); + return use_xp = IsThemeActive() && (IsAppThemed() || !QCoreApplication::instance()); } /* \internal @@ -241,7 +241,7 @@ void QWindowsXPStylePrivate::init(bool force) ref.ref(); useXP(true); - std::fill(m_themes, m_themes + NThemes, HTHEME(0)); + std::fill(m_themes, m_themes + NThemes, nullptr); } /* \internal @@ -253,12 +253,12 @@ void QWindowsXPStylePrivate::cleanup(bool force) if (bufferDC && nullBitmap) SelectObject(bufferDC, nullBitmap); DeleteObject(bufferBitmap); - bufferBitmap = 0; + bufferBitmap = nullptr; } if(bufferDC) DeleteDC(bufferDC); - bufferDC = 0; + bufferDC = nullptr; if (ref.deref() && !force) return; @@ -282,7 +282,7 @@ void QWindowsXPStylePrivate::cleanup(bool force) static inline HWND createTreeViewHelperWindow() { if (QPlatformNativeInterface *ni = QGuiApplication::platformNativeInterface()) { - void *hwnd = 0; + void *hwnd = nullptr; void *wndProc = reinterpret_cast<void *>(DefWindowProc); if (QMetaObject::invokeMethod(ni, "createMessageWindow", Qt::DirectConnection, Q_RETURN_ARG(void*, hwnd), @@ -292,7 +292,7 @@ static inline HWND createTreeViewHelperWindow() return reinterpret_cast<HWND>(hwnd); } } - return 0; + return nullptr; } bool QWindowsXPStylePrivate::initVistaTreeViewTheming() @@ -305,7 +305,7 @@ bool QWindowsXPStylePrivate::initVistaTreeViewTheming() qWarning("Unable to create the treeview helper window."); return false; } - if (FAILED(SetWindowTheme(m_vistaTreeViewHelper, L"explorer", NULL))) { + if (FAILED(SetWindowTheme(m_vistaTreeViewHelper, L"explorer", nullptr))) { qErrnoWarning("SetWindowTheme() failed."); cleanupVistaTreeViewTheming(); return false; @@ -317,7 +317,7 @@ void QWindowsXPStylePrivate::cleanupVistaTreeViewTheming() { if (m_vistaTreeViewHelper) { DestroyWindow(m_vistaTreeViewHelper); - m_vistaTreeViewHelper = 0; + m_vistaTreeViewHelper = nullptr; } } @@ -328,11 +328,12 @@ void QWindowsXPStylePrivate::cleanupVistaTreeViewTheming() */ void QWindowsXPStylePrivate::cleanupHandleMap() { - for (int i = 0; i < NThemes; ++i) - if (m_themes[i]) { - CloseThemeData(m_themes[i]); - m_themes[i] = 0; + for (auto &theme : m_themes) { + if (theme) { + CloseThemeData(theme); + theme = nullptr; } + } QWindowsXPStylePrivate::cleanupVistaTreeViewTheming(); } @@ -340,7 +341,7 @@ HTHEME QWindowsXPStylePrivate::createTheme(int theme, HWND hwnd) { if (Q_UNLIKELY(theme < 0 || theme >= NThemes || !hwnd)) { qWarning("Invalid parameters #%d, %p", theme, hwnd); - return 0; + return nullptr; } if (!m_themes[theme]) { const wchar_t *name = themeNames[theme]; @@ -427,16 +428,16 @@ HBITMAP QWindowsXPStylePrivate::buffer(int w, int h) if (bufferDC && nullBitmap) SelectObject(bufferDC, nullBitmap); DeleteObject(bufferBitmap); - bufferBitmap = 0; + bufferBitmap = nullptr; } w = qMax(bufferW, w); h = qMax(bufferH, h); if (!bufferDC) { - HDC displayDC = GetDC(0); + HDC displayDC = GetDC(nullptr); bufferDC = CreateCompatibleDC(displayDC); - ReleaseDC(0, displayDC); + ReleaseDC(nullptr, displayDC); } // Define the header @@ -450,22 +451,22 @@ HBITMAP QWindowsXPStylePrivate::buffer(int w, int h) bmi.bmiHeader.biCompression = BI_RGB; // Create the pixmap - bufferPixels = 0; - bufferBitmap = CreateDIBSection(bufferDC, &bmi, DIB_RGB_COLORS, (void **) &bufferPixels, 0, 0); + bufferPixels = nullptr; + bufferBitmap = CreateDIBSection(bufferDC, &bmi, DIB_RGB_COLORS, reinterpret_cast<void **>(&bufferPixels), nullptr, 0); GdiFlush(); - nullBitmap = (HBITMAP)SelectObject(bufferDC, bufferBitmap); + nullBitmap = static_cast<HBITMAP>(SelectObject(bufferDC, bufferBitmap)); if (Q_UNLIKELY(!bufferBitmap)) { qErrnoWarning("QWindowsXPStylePrivate::buffer(%dx%d), CreateDIBSection() failed.", w, h); bufferW = 0; bufferH = 0; - return 0; + return nullptr; } if (Q_UNLIKELY(!bufferPixels)) { qErrnoWarning("QWindowsXPStylePrivate::buffer(%dx%d), CreateDIBSection() did not allocate pixel data.", w, h); bufferW = 0; bufferH = 0; - return 0; + return nullptr; } bufferW = w; bufferH = h; @@ -493,7 +494,7 @@ bool QWindowsXPStylePrivate::isTransparent(XPThemeData &themeData) */ QRegion QWindowsXPStylePrivate::region(XPThemeData &themeData) { - HRGN hRgn = 0; + HRGN hRgn = nullptr; const qreal factor = QWindowsStylePrivate::nativeMetricScaleFactor(themeData.widget); RECT rect = themeData.toRECT(QRect(themeData.rect.topLeft() / factor, themeData.rect.size() / factor)); if (!SUCCEEDED(GetThemeBackgroundRegion(themeData.handle(), bufferHDC(), themeData.partId, @@ -502,12 +503,12 @@ QRegion QWindowsXPStylePrivate::region(XPThemeData &themeData) } HRGN dest = CreateRectRgn(0, 0, 0, 0); - const bool success = CombineRgn(dest, hRgn, 0, RGN_COPY) != ERROR; + const bool success = CombineRgn(dest, hRgn, nullptr, RGN_COPY) != ERROR; QRegion region; if (success) { - int numBytes = GetRegionData(dest, 0, 0); + const auto numBytes = GetRegionData(dest, 0, nullptr); if (numBytes == 0) return QRegion(); @@ -551,7 +552,7 @@ bool QWindowsXPStylePrivate::hasAlphaChannel(const QRect &rect) int firstAlpha = -1; for (int y = startY; y < h/2; ++y) { - DWORD *buffer = (DWORD*)bufferPixels + (y * bufferW); + auto buffer = reinterpret_cast<const DWORD *>(bufferPixels) + (y * bufferW); for (int x = startX; x < w; ++x, ++buffer) { int alpha = (*buffer) >> 24; if (firstAlpha == -1) @@ -580,7 +581,7 @@ bool QWindowsXPStylePrivate::fixAlphaChannel(const QRect &rect) bool hasFixedAlphaValue = false; for (int y = startY; y < h; ++y) { - DWORD *buffer = (DWORD*)bufferPixels + (y * bufferW); + auto buffer = reinterpret_cast<DWORD *>(bufferPixels) + (y * bufferW); for (int x = startX; x < w; ++x, ++buffer) { uint pixel = *buffer; int alpha = qAlpha(pixel); @@ -612,7 +613,7 @@ bool QWindowsXPStylePrivate::swapAlphaChannel(const QRect &rect, bool allPixels) // Flip the alphas, so that 255-alpha pixels are 0, and 0-alpha are 255. for (int y = startY; y < h; ++y) { - DWORD *buffer = (DWORD*)bufferPixels + (y * bufferW); + auto buffer = reinterpret_cast<DWORD *>(bufferPixels) + (y * bufferW); for (int x = startX; x < w; ++x, ++buffer) { if (allPixels) { *buffer |= 0xFF000000; @@ -668,7 +669,7 @@ bool QWindowsXPStylePrivate::drawBackground(XPThemeData &themeData) return true; QPainter *painter = themeData.painter; - Q_ASSERT_X(painter != 0, "QWindowsXPStylePrivate::drawBackground()", "Trying to draw a theme part without a painter"); + Q_ASSERT_X(painter != nullptr, "QWindowsXPStylePrivate::drawBackground()", "Trying to draw a theme part without a painter"); if (!painter || !painter->isActive()) return false; @@ -706,7 +707,7 @@ bool QWindowsXPStylePrivate::drawBackground(XPThemeData &themeData) } } - const HDC dc = canDrawDirectly ? hdcForWidgetBackingStore(themeData.widget) : HDC(0); + const HDC dc = canDrawDirectly ? hdcForWidgetBackingStore(themeData.widget) : nullptr; const bool result = dc ? drawBackgroundDirectly(dc, themeData, aditionalDevicePixelRatio) : drawBackgroundThruNativeBuffer(themeData, aditionalDevicePixelRatio); @@ -740,7 +741,7 @@ bool QWindowsXPStylePrivate::drawBackgroundDirectly(HDC dc, XPThemeData &themeDa { QPainter *painter = themeData.painter; - const auto deviceTransform = painter->deviceTransform(); + const auto &deviceTransform = painter->deviceTransform(); const QPointF redirectionDelta(deviceTransform.dx(), deviceTransform.dy()); const QRect area = scaleRect(QRectF(themeData.rect), additionalDevicePixelRatio).translated(redirectionDelta).toRect(); @@ -771,7 +772,7 @@ bool QWindowsXPStylePrivate::drawBackgroundDirectly(HDC dc, XPThemeData &themeDa | (themeData.mirrorHorizontally ? DTBG_MIRRORDC : 0); const HRESULT result = DrawThemeBackgroundEx(themeData.handle(), dc, themeData.partId, themeData.stateId, &(drawRECT), &drawOptions); - SelectClipRgn(dc, 0); + SelectClipRgn(dc, nullptr); DeleteObject(hrgn); return SUCCEEDED(result); } @@ -1099,9 +1100,7 @@ QWindowsXPStyle::QWindowsXPStyle() /*! Destroys the style. */ -QWindowsXPStyle::~QWindowsXPStyle() -{ -} +QWindowsXPStyle::~QWindowsXPStyle() = default; /*! \reimp */ void QWindowsXPStyle::unpolish(QApplication *app) @@ -1157,7 +1156,7 @@ void QWindowsXPStyle::polish(QWidget *widget) if (!d->hasInitColors) { // Get text color for group box labels COLORREF cref; - XPThemeData theme(widget, 0, QWindowsXPStylePrivate::ButtonTheme, 0, 0); + XPThemeData theme(widget, nullptr, QWindowsXPStylePrivate::ButtonTheme, 0, 0); GetThemeColor(theme.handle(), BP_GROUPBOX, GBS_NORMAL, TMT_TEXTCOLOR, &cref); d->groupBoxTextColor = qRgb(GetRValue(cref), GetGValue(cref), GetBValue(cref)); GetThemeColor(theme.handle(), BP_GROUPBOX, GBS_DISABLED, TMT_TEXTCOLOR, &cref); @@ -1270,7 +1269,7 @@ QRect QWindowsXPStyle::subElementRect(SubElement sr, const QStyleOption *option, if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) { MARGINS borderSize; if (widget) { - XPThemeData buttontheme(widget, 0, QWindowsXPStylePrivate::ButtonTheme); + XPThemeData buttontheme(widget, nullptr, QWindowsXPStylePrivate::ButtonTheme); HTHEME theme = buttontheme.handle(); if (theme) { int stateId; @@ -1288,7 +1287,7 @@ QRect QWindowsXPStyle::subElementRect(SubElement sr, const QStyleOption *option, int border = proxy()->pixelMetric(PM_DefaultFrameWidth, btn, widget); rect = option->rect.adjusted(border, border, -border, -border); - if (SUCCEEDED(GetThemeMargins(theme, NULL, BP_PUSHBUTTON, stateId, TMT_CONTENTMARGINS, NULL, &borderSize))) { + if (SUCCEEDED(GetThemeMargins(theme, nullptr, BP_PUSHBUTTON, stateId, TMT_CONTENTMARGINS, nullptr, &borderSize))) { rect.adjust(borderSize.cxLeftWidth, borderSize.cyTopHeight, -borderSize.cxRightWidth, -borderSize.cyBottomHeight); rect = visualRect(option->direction, option->rect, rect); @@ -1468,7 +1467,7 @@ case PE_Frame: return; themeNumber = QWindowsXPStylePrivate::ListViewTheme; partId = LVP_LISTGROUP; - XPThemeData theme(widget, 0, themeNumber, partId, 0); + XPThemeData theme(widget, nullptr, themeNumber, partId); if (!(flags & State_Enabled)) stateId = ETS_DISABLED; @@ -1486,16 +1485,19 @@ case PE_Frame: // Inner white border p->setPen(QPen(option->palette.base().color(), 0)); - p->drawRect(QRectF(option->rect).adjusted(QStyleHelper::dpiScaled(0.5), QStyleHelper::dpiScaled(0.5), - QStyleHelper::dpiScaled(-1), QStyleHelper::dpiScaled(-1))); + const qreal dpi = QStyleHelper::dpi(option); + const auto topLevelAdjustment = QStyleHelper::dpiScaled(0.5, dpi); + const auto bottomRightAdjustment = QStyleHelper::dpiScaled(-1, dpi); + p->drawRect(QRectF(option->rect).adjusted(topLevelAdjustment, topLevelAdjustment, + bottomRightAdjustment, bottomRightAdjustment)); // Outer dark border p->setPen(QPen(bordercolor, 0)); - p->drawRect(QRectF(option->rect).adjusted(0, 0, QStyleHelper::dpiScaled(-0.5), QStyleHelper::dpiScaled(-0.5))); + p->drawRect(QRectF(option->rect).adjusted(0, 0, -topLevelAdjustment, -topLevelAdjustment)); p->setPen(oldPen); return; - } else if (fillType == BT_NONE) { - return; } + if (fillType == BT_NONE) + return; } break; } @@ -1511,7 +1513,8 @@ case PE_Frame: p->drawRect(option->rect.adjusted(0, 0, -1, -1)); p->setPen(oldPen); return; - } else if (qstyleoption_cast<const QStyleOptionFrame *>(option)) { + } + if (qstyleoption_cast<const QStyleOptionFrame *>(option)) { themeNumber = QWindowsXPStylePrivate::EditTheme; partId = EP_EDITTEXT; noContent = true; @@ -1535,7 +1538,7 @@ case PE_Frame: if (QWindowsXPStylePrivate::isLineEditBaseColorSet(option, widget)) { p->fillRect(panel->rect, panel->palette.brush(QPalette::Base)); } else { - XPThemeData theme(0, p, themeNumber, partId, stateId, rect); + XPThemeData theme(nullptr, p, themeNumber, partId, stateId, rect); if (!theme.isValid()) { QWindowsStyle::drawPrimitive(pe, option, p, widget); return; @@ -1584,9 +1587,9 @@ case PE_Frame: wchar_t themeFileName[maxlength]; wchar_t themeColor[maxlength]; // Due to a a scaling issue with the XP Silver theme, tab gradients are not used with it - if (GetCurrentThemeName(themeFileName, maxlength, themeColor, maxlength, NULL, 0) == S_OK) { - wchar_t *offset = 0; - if ((offset = wcsrchr(themeFileName, QChar(QLatin1Char('\\')).unicode())) != NULL) { + if (GetCurrentThemeName(themeFileName, maxlength, themeColor, maxlength, nullptr, 0) == S_OK) { + wchar_t *offset = nullptr; + if ((offset = wcsrchr(themeFileName, QChar(QLatin1Char('\\')).unicode())) != nullptr) { offset++; if (!lstrcmp(offset, L"Luna.msstyles") && !lstrcmp(offset, L"Metallic")) { useGradient = false; @@ -1817,7 +1820,7 @@ case PE_Frame: bef_v -= delta; aft_h += delta; aft_v += delta; - XPThemeData theme(0, p, QWindowsXPStylePrivate::XpTreeViewTheme); + XPThemeData theme(nullptr, p, QWindowsXPStylePrivate::XpTreeViewTheme); theme.rect = QRect(bef_h, bef_v, decoration_size, decoration_size); theme.partId = TVP_GLYPH; theme.stateId = flags & QStyle::State_Open ? GLPS_OPENED : GLPS_CLOSED; @@ -1909,7 +1912,7 @@ void QWindowsXPStyle::drawControl(ControlElement element, const QStyleOption *op { themeNumber = QWindowsXPStylePrivate::StatusTheme; partId = SP_GRIPPER; - XPThemeData theme(0, p, themeNumber, partId, 0); + XPThemeData theme(nullptr, p, themeNumber, partId); QSize size = (theme.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget)).toSize(); size.rheight()--; if (const QStyleOptionSizeGrip *sg = qstyleoption_cast<const QStyleOptionSizeGrip *>(option)) { @@ -1977,7 +1980,7 @@ void QWindowsXPStyle::drawControl(ControlElement element, const QStyleOption *op if (btn->features & QStyleOptionButton::HasMenu) { int mbiw = 0, mbih = 0; - XPThemeData theme(widget, 0, + XPThemeData theme(widget, nullptr, QWindowsXPStylePrivate::ToolBarTheme, TP_SPLITBUTTONDROPDOWN); if (theme.isValid()) { @@ -2306,7 +2309,7 @@ void QWindowsXPStyle::drawControl(ControlElement element, const QStyleOption *op if (isFloating) { titleRect.adjust(0, -fw, 0, 0); - if (widget != 0 && widget->windowIcon().cacheKey() != QApplication::windowIcon().cacheKey()) + if (widget != nullptr && widget->windowIcon().cacheKey() != QApplication::windowIcon().cacheKey()) titleRect.adjust(titleRect.height() + mw, 0, 0, 0); } else { titleRect.adjust(mw, 0, 0, 0); @@ -2772,7 +2775,7 @@ void QWindowsXPStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCo break; v = nextInterval; } - if (lines.size() > 0) { + if (!lines.isEmpty()) { p->save(); p->translate(slrect.topLeft()); p->drawLines(lines.constData(), lines.size()); @@ -2920,7 +2923,7 @@ void QWindowsXPStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCo p->save(); p->setClipRect(menuarea); tool.rect = option->rect; - proxy()->drawPrimitive(PE_PanelButtonBevel, &tool, p, 0); + proxy()->drawPrimitive(PE_PanelButtonBevel, &tool, p, nullptr); p->restore(); } // Draw arrow @@ -3220,7 +3223,7 @@ void QWindowsXPStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCo } } -static inline Qt::Orientation progressBarOrientation(const QStyleOption *option = 0) +static inline Qt::Orientation progressBarOrientation(const QStyleOption *option = nullptr) { if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) return pb->orientation; @@ -3231,27 +3234,27 @@ int QWindowsXPStylePrivate::pixelMetricFromSystemDp(QStyle::PixelMetric pm, cons { switch (pm) { case QStyle::PM_IndicatorWidth: - return XPThemeData::themeSize(widget, 0, QWindowsXPStylePrivate::ButtonTheme, BP_CHECKBOX, CBS_UNCHECKEDNORMAL).width(); + return XPThemeData::themeSize(widget, nullptr, QWindowsXPStylePrivate::ButtonTheme, BP_CHECKBOX, CBS_UNCHECKEDNORMAL).width(); case QStyle::PM_IndicatorHeight: - return XPThemeData::themeSize(widget, 0, QWindowsXPStylePrivate::ButtonTheme, BP_CHECKBOX, CBS_UNCHECKEDNORMAL).height(); + return XPThemeData::themeSize(widget, nullptr, QWindowsXPStylePrivate::ButtonTheme, BP_CHECKBOX, CBS_UNCHECKEDNORMAL).height(); case QStyle::PM_ExclusiveIndicatorWidth: - return XPThemeData::themeSize(widget, 0, QWindowsXPStylePrivate::ButtonTheme, BP_RADIOBUTTON, RBS_UNCHECKEDNORMAL).width(); + return XPThemeData::themeSize(widget, nullptr, QWindowsXPStylePrivate::ButtonTheme, BP_RADIOBUTTON, RBS_UNCHECKEDNORMAL).width(); case QStyle::PM_ExclusiveIndicatorHeight: - return XPThemeData::themeSize(widget, 0, QWindowsXPStylePrivate::ButtonTheme, BP_RADIOBUTTON, RBS_UNCHECKEDNORMAL).height(); + return XPThemeData::themeSize(widget, nullptr, QWindowsXPStylePrivate::ButtonTheme, BP_RADIOBUTTON, RBS_UNCHECKEDNORMAL).height(); case QStyle::PM_ProgressBarChunkWidth: return progressBarOrientation(option) == Qt::Horizontal - ? XPThemeData::themeSize(widget, 0, QWindowsXPStylePrivate::ProgressTheme, PP_CHUNK).width() - : XPThemeData::themeSize(widget, 0, QWindowsXPStylePrivate::ProgressTheme, PP_CHUNKVERT).height(); + ? XPThemeData::themeSize(widget, nullptr, QWindowsXPStylePrivate::ProgressTheme, PP_CHUNK).width() + : XPThemeData::themeSize(widget, nullptr, QWindowsXPStylePrivate::ProgressTheme, PP_CHUNKVERT).height(); case QStyle::PM_SliderThickness: - return XPThemeData::themeSize(widget, 0, QWindowsXPStylePrivate::TrackBarTheme, TKP_THUMB).height(); + return XPThemeData::themeSize(widget, nullptr, QWindowsXPStylePrivate::TrackBarTheme, TKP_THUMB).height(); case QStyle::PM_TitleBarHeight: return widget && (widget->windowType() == Qt::Tool) ? GetSystemMetrics(SM_CYSMCAPTION) + GetSystemMetrics(SM_CXSIZEFRAME) : GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CXSIZEFRAME); case QStyle::PM_MdiSubWindowFrameWidth: - return XPThemeData::themeSize(widget, 0, QWindowsXPStylePrivate::WindowTheme, WP_FRAMELEFT, FS_ACTIVE).width(); + return XPThemeData::themeSize(widget, nullptr, QWindowsXPStylePrivate::WindowTheme, WP_FRAMELEFT, FS_ACTIVE).width(); case QStyle::PM_DockWidgetFrameWidth: - return XPThemeData::themeSize(widget, 0, QWindowsXPStylePrivate::WindowTheme, WP_SMALLFRAMERIGHT, FS_ACTIVE).width(); + return XPThemeData::themeSize(widget, nullptr, QWindowsXPStylePrivate::WindowTheme, WP_SMALLFRAMERIGHT, FS_ACTIVE).width(); default: break; } @@ -3311,7 +3314,8 @@ int QWindowsXPStyle::pixelMetric(PixelMetric pm, const QStyleOption *option, con break; case PM_SplitterWidth: - res = qMax(int(QStyleHelper::dpiScaled(5.)), QApplication::globalStrut().width()); + res = qMax(int(QStyleHelper::dpiScaled(5., option)), + QApplication::globalStrut().width()); break; case PM_MdiSubWindowMinimizedWidth: @@ -3320,13 +3324,13 @@ int QWindowsXPStyle::pixelMetric(PixelMetric pm, const QStyleOption *option, con #if QT_CONFIG(toolbar) case PM_ToolBarHandleExtent: - res = int(QStyleHelper::dpiScaled(8.)); + res = int(QStyleHelper::dpiScaled(8., option)); break; #endif // QT_CONFIG(toolbar) case PM_DockWidgetSeparatorExtent: case PM_DockWidgetTitleMargin: - res = int(QStyleHelper::dpiScaled(4.)); + res = int(QStyleHelper::dpiScaled(4., option)); break; case PM_ButtonShiftHorizontal: @@ -3411,7 +3415,7 @@ QRect QWindowsXPStyle::subControlRect(ComplexControl cc, const QStyleOptionCompl const bool isToolTitle = false; const int height = tb->rect.height(); const int width = tb->rect.width(); - const int buttonMargin = int(QStyleHelper::dpiScaled(4)); + const int buttonMargin = int(QStyleHelper::dpiScaled(4, option)); const qreal factor = QWindowsStylePrivate::nativeMetricScaleFactor(widget); int buttonHeight = qRound(qreal(GetSystemMetrics(SM_CYSIZE)) * factor) - buttonMargin; @@ -3522,21 +3526,28 @@ QRect QWindowsXPStyle::subControlRect(ComplexControl cc, const QStyleOptionCompl case CC_ComboBox: if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) { const int x = cmb->rect.x(), y = cmb->rect.y(), wi = cmb->rect.width(), he = cmb->rect.height(); - const int xpos = x + wi - qRound(QStyleHelper::dpiScaled(1 + 16)); + const int xpos = x + wi - qRound(QStyleHelper::dpiScaled(1 + 16, option)); switch (subControl) { case SC_ComboBoxFrame: rect = cmb->rect; break; - case SC_ComboBoxArrow: - rect = QRect(xpos, y + qRound(QStyleHelper::dpiScaled(1)), - qRound(QStyleHelper::dpiScaled(16)), he - qRound(QStyleHelper::dpiScaled(2))); + case SC_ComboBoxArrow: { + const qreal dpi = QStyleHelper::dpi(option); + rect = QRect(xpos, y + qRound(QStyleHelper::dpiScaled(1, dpi)), + qRound(QStyleHelper::dpiScaled(16, dpi)), + he - qRound(QStyleHelper::dpiScaled(2, dpi))); + } break; - case SC_ComboBoxEditField: - rect = QRect(x + qRound(QStyleHelper::dpiScaled(2)), y + qRound(QStyleHelper::dpiScaled(2)), - wi - qRound(QStyleHelper::dpiScaled(3 + 16)), he - qRound(QStyleHelper::dpiScaled(4))); + case SC_ComboBoxEditField: { + const qreal dpi = QStyleHelper::dpi(option); + const int frame = qRound(QStyleHelper::dpiScaled(2, dpi)); + rect = QRect(x + frame, y + frame, + wi - qRound(QStyleHelper::dpiScaled(3 + 16, dpi)), + he - qRound(QStyleHelper::dpiScaled(4, dpi))); + } break; case SC_ComboBoxListBoxPopup: @@ -3609,7 +3620,7 @@ QSize QWindowsXPStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt case CT_LineEdit: case CT_ComboBox: { - XPThemeData buttontheme(widget, 0, QWindowsXPStylePrivate::ButtonTheme, BP_PUSHBUTTON, PBS_NORMAL); + XPThemeData buttontheme(widget, nullptr, QWindowsXPStylePrivate::ButtonTheme, BP_PUSHBUTTON, PBS_NORMAL); if (buttontheme.isValid()) { const qreal factor = QWindowsXPStylePrivate::nativeMetricScaleFactor(widget); const QMarginsF borderSize = buttontheme.margins() * factor; @@ -3730,11 +3741,11 @@ int QWindowsXPStyle::styleHint(StyleHint hint, const QStyleOption *option, const titleBarRect.setHeight(tbHeight); XPThemeData themeData; if (titlebar->titleBarState & Qt::WindowMinimized) { - themeData = XPThemeData(widget, 0, + themeData = XPThemeData(widget, nullptr, QWindowsXPStylePrivate::WindowTheme, WP_MINCAPTION, CS_ACTIVE, titleBarRect); } else - themeData = XPThemeData(widget, 0, + themeData = XPThemeData(widget, nullptr, QWindowsXPStylePrivate::WindowTheme, WP_CAPTION, CS_ACTIVE, titleBarRect); mask->region = d->region(themeData) + @@ -3763,10 +3774,8 @@ int QWindowsXPStyle::styleHint(StyleHint hint, const QStyleOption *option, const /*! \reimp */ QPalette QWindowsXPStyle::standardPalette() const { - if (QWindowsXPStylePrivate::useXP() && QApplicationPrivate::sys_pal) - return *QApplicationPrivate::sys_pal; - else - return QWindowsStyle::standardPalette(); + return QWindowsXPStylePrivate::useXP() && QApplicationPrivate::sys_pal + ? *QApplicationPrivate::sys_pal : QWindowsStyle::standardPalette(); } /*! @@ -3784,7 +3793,7 @@ QPixmap QWindowsXPStyle::standardPixmap(StandardPixmap standardPixmap, const QSt if (qstyleoption_cast<const QStyleOptionDockWidget *>(option)) { if (widget && widget->isWindow()) { - XPThemeData theme(widget, 0, QWindowsXPStylePrivate::WindowTheme, WP_SMALLCLOSEBUTTON, CBS_NORMAL); + XPThemeData theme(widget, nullptr, QWindowsXPStylePrivate::WindowTheme, WP_SMALLCLOSEBUTTON, CBS_NORMAL); if (theme.isValid()) { const QSize size = (theme.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget)).toSize(); return QIcon(QWindowsStyle::standardPixmap(standardPixmap, option, widget)).pixmap(size); @@ -3815,9 +3824,9 @@ QIcon QWindowsXPStyle::standardIcon(StandardPixmap standardIcon, if (qstyleoption_cast<const QStyleOptionDockWidget *>(option)) { if (d->dockFloat.isNull()) { - XPThemeData themeSize(0, 0, QWindowsXPStylePrivate::WindowTheme, + XPThemeData themeSize(nullptr, nullptr, QWindowsXPStylePrivate::WindowTheme, WP_SMALLCLOSEBUTTON, CBS_NORMAL); - XPThemeData theme(0, 0, QWindowsXPStylePrivate::WindowTheme, + XPThemeData theme(nullptr, nullptr, QWindowsXPStylePrivate::WindowTheme, WP_MAXBUTTON, MAXBS_NORMAL); if (theme.isValid()) { const QSize size = (themeSize.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget)).toSize(); @@ -3851,7 +3860,7 @@ QIcon QWindowsXPStyle::standardIcon(StandardPixmap standardIcon, if (qstyleoption_cast<const QStyleOptionDockWidget *>(option)) { if (d->dockClose.isNull()) { - XPThemeData theme(0, 0, QWindowsXPStylePrivate::WindowTheme, + XPThemeData theme(nullptr, nullptr, QWindowsXPStylePrivate::WindowTheme, WP_SMALLCLOSEBUTTON, CBS_NORMAL); if (theme.isValid()) { const QSize size = (theme.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget)).toSize(); @@ -3885,9 +3894,9 @@ QIcon QWindowsXPStyle::standardIcon(StandardPixmap standardIcon, if (qstyleoption_cast<const QStyleOptionDockWidget *>(option)) { if (d->dockFloat.isNull()) { - XPThemeData themeSize(0, 0, QWindowsXPStylePrivate::WindowTheme, + XPThemeData themeSize(nullptr, nullptr, QWindowsXPStylePrivate::WindowTheme, WP_SMALLCLOSEBUTTON, CBS_NORMAL); - XPThemeData theme(0, 0, QWindowsXPStylePrivate::WindowTheme, + XPThemeData theme(nullptr, nullptr, QWindowsXPStylePrivate::WindowTheme, WP_RESTOREBUTTON, RBS_NORMAL); if (theme.isValid()) { const QSize size = (themeSize.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget)).toSize(); diff --git a/src/plugins/styles/windowsvista/qwindowsxpstyle_p_p.h b/src/plugins/styles/windowsvista/qwindowsxpstyle_p_p.h index 60f9d7e9b7..ad7754e3d4 100644 --- a/src/plugins/styles/windowsvista/qwindowsxpstyle_p_p.h +++ b/src/plugins/styles/windowsvista/qwindowsxpstyle_p_p.h @@ -100,11 +100,11 @@ class QDebug; class XPThemeData { public: - explicit XPThemeData(const QWidget *w = 0, QPainter *p = 0, int themeIn = -1, + explicit XPThemeData(const QWidget *w = nullptr, QPainter *p = nullptr, int themeIn = -1, int part = 0, int state = 0, const QRect &r = QRect()) - : widget(w), painter(p), theme(themeIn), htheme(0), partId(part), stateId(state), + : widget(w), painter(p), theme(themeIn), partId(part), stateId(state), mirrorHorizontally(false), mirrorVertically(false), noBorder(false), - noContent(false), rotate(0), rect(r) + noContent(false), rect(r) {} HRGN mask(QWidget *widget); @@ -117,17 +117,17 @@ public: QMarginsF margins(const QRect &rect, int propId = TMT_CONTENTMARGINS); QMarginsF margins(int propId = TMT_CONTENTMARGINS); - static QSizeF themeSize(const QWidget *w = 0, QPainter *p = 0, int themeIn = -1, int part = 0, int state = 0); - static QMarginsF themeMargins(const QRect &rect, const QWidget *w = 0, QPainter *p = 0, int themeIn = -1, + static QSizeF themeSize(const QWidget *w = nullptr, QPainter *p = nullptr, int themeIn = -1, int part = 0, int state = 0); + static QMarginsF themeMargins(const QRect &rect, const QWidget *w = nullptr, QPainter *p = nullptr, int themeIn = -1, int part = 0, int state = 0, int propId = TMT_CONTENTMARGINS); - static QMarginsF themeMargins(const QWidget *w = 0, QPainter *p = 0, int themeIn = -1, + static QMarginsF themeMargins(const QWidget *w = nullptr, QPainter *p = nullptr, int themeIn = -1, int part = 0, int state = 0, int propId = TMT_CONTENTMARGINS); const QWidget *widget; QPainter *painter; int theme; - HTHEME htheme; + HTHEME htheme = nullptr; int partId; int stateId; @@ -135,18 +135,18 @@ public: uint mirrorVertically : 1; uint noBorder : 1; uint noContent : 1; - uint rotate; + uint rotate = 0; QRect rect; }; struct ThemeMapKey { - int theme; - int partId; - int stateId; - bool noBorder; - bool noContent; + int theme = 0; + int partId = -1; + int stateId = -1; + bool noBorder = false; + bool noContent = false; - ThemeMapKey() : partId(-1), stateId(-1) {} + ThemeMapKey() = default; ThemeMapKey(const XPThemeData &data) : theme(data.theme), partId(data.partId), stateId(data.stateId), noBorder(data.noBorder), noContent(data.noContent) {} @@ -171,7 +171,7 @@ enum AlphaChannelType { }; struct ThemeMapData { - AlphaChannelType alphaType; // Which type of alpha on part & state + AlphaChannelType alphaType = UnknownAlpha; // Which type of alpha on part & state bool dataValid : 1; // Only used to detect if hash value is ok bool partIsTransparent : 1; @@ -217,15 +217,13 @@ public: }; QWindowsXPStylePrivate() - : QWindowsStylePrivate(), hasInitColors(false), bufferDC(0), bufferBitmap(0), nullBitmap(0), - bufferPixels(0), bufferW(0), bufferH(0) { init(); } ~QWindowsXPStylePrivate() { cleanup(); } - static int pixelMetricFromSystemDp(QStyle::PixelMetric pm, const QStyleOption *option = 0, const QWidget *widget = 0); - static int fixedPixelMetric(QStyle::PixelMetric pm, const QStyleOption *option = 0, const QWidget *widget = 0); + static int pixelMetricFromSystemDp(QStyle::PixelMetric pm, const QStyleOption *option = nullptr, const QWidget *widget = nullptr); + static int fixedPixelMetric(QStyle::PixelMetric pm, const QStyleOption *option = nullptr, const QWidget *widget = nullptr); static HWND winId(const QWidget *widget); @@ -251,10 +249,10 @@ public: bool fixAlphaChannel(const QRect &rect); bool swapAlphaChannel(const QRect &rect, bool allPixels = false); - QRgb groupBoxTextColor; - QRgb groupBoxTextColorDisabled; - QRgb sliderTickColor; - bool hasInitColors; + QRgb groupBoxTextColor = 0; + QRgb groupBoxTextColorDisabled = 0; + QRgb sliderTickColor = 0; + bool hasInitColors = false; static HTHEME createTheme(int theme, HWND hwnd); static QString themeName(int theme); @@ -277,11 +275,12 @@ private: static bool use_xp; QHash<ThemeMapKey, ThemeMapData> alphaCache; - HDC bufferDC; - HBITMAP bufferBitmap; - HBITMAP nullBitmap; - uchar *bufferPixels; - int bufferW, bufferH; + HDC bufferDC = nullptr; + HBITMAP bufferBitmap = nullptr; + HBITMAP nullBitmap = nullptr; + uchar *bufferPixels = nullptr; + int bufferW = 0; + int bufferH = 0; static HWND m_vistaTreeViewHelper; static HTHEME m_themes[NThemes]; @@ -292,7 +291,7 @@ inline QSizeF XPThemeData::size() QSizeF result(0, 0); if (isValid()) { SIZE size; - if (SUCCEEDED(GetThemePartSize(handle(), 0, partId, stateId, 0, TS_TRUE, &size))) + if (SUCCEEDED(GetThemePartSize(handle(), nullptr, partId, stateId, nullptr, TS_TRUE, &size))) result = QSize(size.cx, size.cy); } return result; @@ -304,7 +303,7 @@ inline QMarginsF XPThemeData::margins(const QRect &qRect, int propId) if (isValid()) { MARGINS margins; RECT rect = XPThemeData::toRECT(qRect); - if (SUCCEEDED(GetThemeMargins(handle(), 0, partId, stateId, propId, &rect, &margins))) + if (SUCCEEDED(GetThemeMargins(handle(), nullptr, partId, stateId, propId, &rect, &margins))) result = QMargins(margins.cxLeftWidth, margins.cyTopHeight, margins.cxRightWidth, margins.cyBottomHeight); } return result; @@ -315,7 +314,7 @@ inline QMarginsF XPThemeData::margins(int propId) QMarginsF result(0, 0, 0 ,0); if (isValid()) { MARGINS margins; - if (SUCCEEDED(GetThemeMargins(handle(), 0, partId, stateId, propId, NULL, &margins))) + if (SUCCEEDED(GetThemeMargins(handle(), nullptr, partId, stateId, propId, nullptr, &margins))) result = QMargins(margins.cxLeftWidth, margins.cyTopHeight, margins.cxRightWidth, margins.cyBottomHeight); } return result; diff --git a/src/plugins/styles/windowsvista/windowsvista.pro b/src/plugins/styles/windowsvista/windowsvista.pro index f82bcfc91b..c08db7f533 100644 --- a/src/plugins/styles/windowsvista/windowsvista.pro +++ b/src/plugins/styles/windowsvista/windowsvista.pro @@ -10,7 +10,7 @@ SOURCES += qwindowsvistastyle.cpp HEADERS += qwindowsxpstyle_p.h qwindowsxpstyle_p_p.h SOURCES += qwindowsxpstyle.cpp -LIBS_PRIVATE += -lgdi32 -luser32 +QMAKE_USE_PRIVATE += user32 gdi32 # DEFINES/LIBS needed for qwizard_win.cpp and the styles include(../../../widgets/kernel/win.pri) |