diff options
Diffstat (limited to 'src/plugins')
62 files changed, 1080 insertions, 225 deletions
diff --git a/src/plugins/bearer/qnetworksession_impl.cpp b/src/plugins/bearer/qnetworksession_impl.cpp index 5e9e5e7015..8139040f84 100644 --- a/src/plugins/bearer/qnetworksession_impl.cpp +++ b/src/plugins/bearer/qnetworksession_impl.cpp @@ -279,7 +279,7 @@ quint64 QNetworkSessionPrivateImpl::bytesReceived() const quint64 QNetworkSessionPrivateImpl::activeTime() const { if (state == QNetworkSession::Connected && startTime != Q_UINT64_C(0)) - return QDateTime::currentDateTime().toTime_t() - startTime; + return QDateTime::currentDateTimeUtc().toTime_t() - startTime; return Q_UINT64_C(0); } diff --git a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp index f69bc5e401..0148d36a6c 100644 --- a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp +++ b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp @@ -58,8 +58,6 @@ QT_BEGIN_NAMESPACE -Q_LOGGING_CATEGORY(qtQpaInputMethods, "qt.qpa.input.methods") - enum { debug = 0 }; class QIBusPlatformInputContextPrivate @@ -87,6 +85,7 @@ public: bool busConnected; QString predit; bool needsSurroundingText; + QLocale locale; }; @@ -414,6 +413,11 @@ void QIBusPlatformInputContext::filterEventFinished(QDBusPendingCallWatcher *cal call->deleteLater(); } +QLocale QIBusPlatformInputContext::locale() const +{ + return d->locale; +} + void QIBusPlatformInputContext::socketChanged(const QString &str) { qCDebug(qtQpaInputMethods) << "socketChanged"; @@ -423,6 +427,8 @@ void QIBusPlatformInputContext::socketChanged(const QString &str) if (d->context) disconnect(d->context); + if (d->bus && d->bus->isValid()) + disconnect(d->bus); if (d->connection) d->connection->disconnectFromBus(QLatin1String("QIBusProxy")); @@ -441,8 +447,26 @@ void QIBusPlatformInputContext::connectToBus() m_socketWatcher.addPath(QIBusPlatformInputContextPrivate::getSocketPath()); } +void QIBusPlatformInputContext::globalEngineChanged(const QString &engine_name) +{ + if (!d->bus || !d->bus->isValid()) + return; + + QIBusEngineDesc desc = d->bus->getGlobalEngine(); + Q_ASSERT(engine_name == desc.engine_name); + QLocale locale(desc.language); + if (d->locale != locale) { + d->locale = locale; + emitLocaleChanged(); + } +} + void QIBusPlatformInputContext::connectToContextSignals() { + if (d->bus && d->bus->isValid()) { + connect(d->bus, SIGNAL(GlobalEngineChanged(QString)), this, SLOT(globalEngineChanged(QString))); + } + if (d->context) { connect(d->context, SIGNAL(CommitText(QDBusVariant)), SLOT(commitText(QDBusVariant))); connect(d->context, SIGNAL(UpdatePreeditText(QDBusVariant,uint,bool)), this, SLOT(updatePreeditText(QDBusVariant,uint,bool))); @@ -463,6 +487,11 @@ QIBusPlatformInputContextPrivate::QIBusPlatformInputContextPrivate() if (!valid) return; initBus(); + + if (bus && bus->isValid()) { + QIBusEngineDesc desc = bus->getGlobalEngine(); + locale = QLocale(desc.language); + } } void QIBusPlatformInputContextPrivate::initBus() diff --git a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h index a8efd9deb3..824e9c2073 100644 --- a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h +++ b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h @@ -36,16 +36,14 @@ #include <qpa/qplatforminputcontext.h> #include <QtCore/qpointer.h> +#include <QtCore/QLocale> #include <QtDBus/qdbuspendingreply.h> #include <QFileSystemWatcher> -#include <QLoggingCategory> #include <QTimer> #include <QWindow> QT_BEGIN_NAMESPACE -Q_DECLARE_LOGGING_CATEGORY(qtQpaInputMethods) - class QIBusPlatformInputContextPrivate; class QDBusVariant; @@ -90,6 +88,7 @@ public: void commit() Q_DECL_OVERRIDE; void update(Qt::InputMethodQueries) Q_DECL_OVERRIDE; bool filterEvent(const QEvent *event) Q_DECL_OVERRIDE; + QLocale locale() const Q_DECL_OVERRIDE; public Q_SLOTS: void commitText(const QDBusVariant &text); @@ -100,6 +99,7 @@ public Q_SLOTS: void filterEventFinished(QDBusPendingCallWatcher *call); void socketChanged(const QString &str); void connectToBus(); + void globalEngineChanged(const QString &engine_name); private: QIBusPlatformInputContextPrivate *d; diff --git a/src/plugins/platforminputcontexts/ibus/qibusproxy.cpp b/src/plugins/platforminputcontexts/ibus/qibusproxy.cpp index e6b255a06d..9efa6f7eb0 100644 --- a/src/plugins/platforminputcontexts/ibus/qibusproxy.cpp +++ b/src/plugins/platforminputcontexts/ibus/qibusproxy.cpp @@ -9,6 +9,8 @@ * before re-generating it. */ +#include <QtDBus/qdbusextratypes.h> + #include "qibusproxy.h" /* @@ -18,9 +20,36 @@ QIBusProxy::QIBusProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) { + this->connection().connect(service, + path, + this->interface(), // interface + QStringLiteral("GlobalEngineChanged"), + QStringList(), + QString(), // signature + this, SLOT(globalEngineChanged(QString))); } QIBusProxy::~QIBusProxy() { } +QIBusEngineDesc QIBusProxy::getGlobalEngine() +{ + QIBusEngineDesc desc; + QDBusReply<QDBusVariant> reply = GetGlobalEngine(); + QVariant variant = reply.value().variant(); + if (!variant.isValid()) + return desc; + QVariant child = variant.value<QDBusVariant>().variant(); + if (!child.isValid()) + return desc; + const QDBusArgument argument = child.value<QDBusArgument>(); + argument >> desc; + return desc; +} + +void QIBusProxy::globalEngineChanged(const QString &engine_name) +{ + emit GlobalEngineChanged(engine_name); +} + diff --git a/src/plugins/platforminputcontexts/ibus/qibusproxy.h b/src/plugins/platforminputcontexts/ibus/qibusproxy.h index 69443a524d..bbaebe1b96 100644 --- a/src/plugins/platforminputcontexts/ibus/qibusproxy.h +++ b/src/plugins/platforminputcontexts/ibus/qibusproxy.h @@ -20,6 +20,8 @@ #include <QtCore/QVariant> #include <QtDBus/QtDBus> +#include "qibustypes.h" + /* * Proxy class for interface org.freedesktop.IBus */ @@ -29,6 +31,8 @@ class QIBusProxy: public QDBusAbstractInterface public: static inline const char *staticInterfaceName() { return "org.freedesktop.IBus"; } + static inline QString dbusInterfaceProperties() + { return QStringLiteral("org.freedesktop.DBus.Properties"); } public: QIBusProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0); @@ -82,7 +86,26 @@ public Q_SLOTS: // METHODS return asyncCallWithArgumentList(QLatin1String("RegisterComponent"), argumentList); } + inline QDBusPendingReply<QDBusVariant> GetGlobalEngine() + { + if (!this->isValid() || this->service().isEmpty() || this->path().isEmpty()) + return QDBusMessage::createError(this->lastError()); + + QDBusMessage msg = QDBusMessage::createMethodCall(this->service(), + this->path(), + dbusInterfaceProperties(), + QStringLiteral("Get")); + msg << this->interface() << QStringLiteral("GlobalEngine"); + return this->connection().asyncCall(msg, this->timeout()); + } + + QIBusEngineDesc getGlobalEngine(); + +private: + void globalEngineChanged(const QString &engine_name); + Q_SIGNALS: // SIGNALS + void GlobalEngineChanged(const QString &engine_name); }; #endif diff --git a/src/plugins/platforminputcontexts/ibus/qibustypes.cpp b/src/plugins/platforminputcontexts/ibus/qibustypes.cpp index f88e5ca5a3..7cf3b24570 100644 --- a/src/plugins/platforminputcontexts/ibus/qibustypes.cpp +++ b/src/plugins/platforminputcontexts/ibus/qibustypes.cpp @@ -37,6 +37,9 @@ QT_BEGIN_NAMESPACE +Q_LOGGING_CATEGORY(qtQpaInputMethods, "qt.qpa.input.methods") +Q_LOGGING_CATEGORY(qtQpaInputMethodsSerialize, "qt.qpa.input.methods.serialize") + QIBusSerializable::QIBusSerializable() { } @@ -202,7 +205,7 @@ QDBusArgument &operator<<(QDBusArgument &argument, const QIBusAttributeList &att const QDBusArgument &operator>>(const QDBusArgument &arg, QIBusAttributeList &attrList) { -// qDebug() << "QIBusAttributeList::fromDBusArgument()" << arg.currentSignature(); + qCDebug(qtQpaInputMethodsSerialize) << "QIBusAttributeList::fromDBusArgument()" << arg.currentSignature(); arg.beginStructure(); arg >> static_cast<QIBusSerializable &>(attrList); @@ -277,7 +280,7 @@ QDBusArgument &operator<<(QDBusArgument &argument, const QIBusText &text) const QDBusArgument &operator>>(const QDBusArgument &argument, QIBusText &text) { -// qDebug() << "QIBusText::fromDBusArgument()" << arg.currentSignature(); + qCDebug(qtQpaInputMethodsSerialize) << "QIBusText::fromDBusArgument()" << argument.currentSignature(); argument.beginStructure(); argument >> static_cast<QIBusSerializable &>(text); @@ -291,4 +294,107 @@ const QDBusArgument &operator>>(const QDBusArgument &argument, QIBusText &text) return argument; } +QIBusEngineDesc::QIBusEngineDesc() + : engine_name(""), + longname(""), + description(""), + language(""), + license(""), + author(""), + icon(""), + layout(""), + rank(0), + hotkeys(""), + symbol(""), + setup(""), + layout_variant(""), + layout_option(""), + version(""), + textdomain(""), + iconpropkey("") +{ + name = "IBusEngineDesc"; +} + +QIBusEngineDesc::~QIBusEngineDesc() +{ +} + +QDBusArgument &operator<<(QDBusArgument &argument, const QIBusEngineDesc &desc) +{ + argument.beginStructure(); + + argument << static_cast<const QIBusSerializable &>(desc); + + argument << desc.engine_name; + argument << desc.longname; + argument << desc.description; + argument << desc.language; + argument << desc.license; + argument << desc.author; + argument << desc.icon; + argument << desc.layout; + argument << desc.rank; + argument << desc.hotkeys; + argument << desc.symbol; + argument << desc.setup; + argument << desc.layout_variant; + argument << desc.layout_option; + argument << desc.version; + argument << desc.textdomain; + argument << desc.iconpropkey; + + argument.endStructure(); + return argument; +} + +const QDBusArgument &operator>>(const QDBusArgument &argument, QIBusEngineDesc &desc) +{ + qCDebug(qtQpaInputMethodsSerialize) << "QIBusEngineDesc::fromDBusArgument()" << argument.currentSignature(); + argument.beginStructure(); + + argument >> static_cast<QIBusSerializable &>(desc); + + argument >> desc.engine_name; + argument >> desc.longname; + argument >> desc.description; + argument >> desc.language; + argument >> desc.license; + argument >> desc.author; + argument >> desc.icon; + argument >> desc.layout; + argument >> desc.rank; + argument >> desc.hotkeys; + argument >> desc.symbol; + argument >> desc.setup; + // Previous IBusEngineDesc supports the arguments between engine_name + // and setup. + if (argument.currentSignature() == "") { + argument.endStructure(); + return argument; + } + argument >> desc.layout_variant; + argument >> desc.layout_option; + // Previous IBusEngineDesc supports the arguments between engine_name + // and layout_option. + if (argument.currentSignature() == "") { + argument.endStructure(); + return argument; + } + argument >> desc.version; + if (argument.currentSignature() == "") { + argument.endStructure(); + return argument; + } + argument >> desc.textdomain; + if (argument.currentSignature() == "") { + argument.endStructure(); + return argument; + } + argument >> desc.iconpropkey; + + argument.endStructure(); + return argument; +} + QT_END_NAMESPACE diff --git a/src/plugins/platforminputcontexts/ibus/qibustypes.h b/src/plugins/platforminputcontexts/ibus/qibustypes.h index cb0d9ff2aa..b4145863bc 100644 --- a/src/plugins/platforminputcontexts/ibus/qibustypes.h +++ b/src/plugins/platforminputcontexts/ibus/qibustypes.h @@ -37,9 +37,13 @@ #include <qevent.h> #include <QDBusArgument> #include <QTextCharFormat> +#include <QLoggingCategory> QT_BEGIN_NAMESPACE +Q_DECLARE_LOGGING_CATEGORY(qtQpaInputMethods) +Q_DECLARE_LOGGING_CATEGORY(qtQpaInputMethodsSerialize) + class QIBusSerializable { public: @@ -100,6 +104,31 @@ public: QIBusAttributeList attributes; }; +class QIBusEngineDesc : public QIBusSerializable +{ +public: + QIBusEngineDesc(); + ~QIBusEngineDesc(); + + QString engine_name; + QString longname; + QString description; + QString language; + QString license; + QString author; + QString icon; + QString layout; + unsigned int rank; + QString hotkeys; + QString symbol; + QString setup; + QString layout_variant; + QString layout_option; + QString version; + QString textdomain; + QString iconpropkey; +}; + QDBusArgument &operator<<(QDBusArgument &argument, const QIBusSerializable &object); const QDBusArgument &operator>>(const QDBusArgument &argument, QIBusSerializable &object); @@ -112,11 +141,15 @@ const QDBusArgument &operator>>(const QDBusArgument &arg, QIBusAttributeList &at QDBusArgument &operator<<(QDBusArgument &argument, const QIBusText &text); const QDBusArgument &operator>>(const QDBusArgument &argument, QIBusText &text); +QDBusArgument &operator<<(QDBusArgument &argument, const QIBusEngineDesc &desc); +const QDBusArgument &operator>>(const QDBusArgument &argument, QIBusEngineDesc &desc); + QT_END_NAMESPACE Q_DECLARE_METATYPE(QIBusSerializable) Q_DECLARE_METATYPE(QIBusAttribute) Q_DECLARE_METATYPE(QIBusAttributeList) Q_DECLARE_METATYPE(QIBusText) +Q_DECLARE_METATYPE(QIBusEngineDesc) #endif diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp index 99cb58830c..d419e42cd5 100644 --- a/src/plugins/platforms/android/androidjnimain.cpp +++ b/src/plugins/platforms/android/androidjnimain.cpp @@ -55,6 +55,7 @@ #include <QtCore/private/qjnihelpers_p.h> #include <QtCore/private/qjni_p.h> #include <QtGui/private/qguiapplication_p.h> +#include <QtGui/private/qhighdpiscaling_p.h> #include <qpa/qwindowsysteminterface.h> @@ -109,6 +110,7 @@ static QAndroidPlatformIntegration *m_androidPlatformIntegration = nullptr; static int m_desktopWidthPixels = 0; static int m_desktopHeightPixels = 0; static double m_scaledDensity = 0; +static double m_density = 1.0; static volatile bool m_pauseApplication; @@ -157,6 +159,11 @@ namespace QtAndroid return m_scaledDensity; } + double pixelDensity() + { + return m_density; + } + JavaVM *javaVM() { return m_javaVM; @@ -547,7 +554,8 @@ static void setSurface(JNIEnv *env, jobject /*thiz*/, jint id, jobject jSurface, static void setDisplayMetrics(JNIEnv */*env*/, jclass /*clazz*/, jint widthPixels, jint heightPixels, jint desktopWidthPixels, jint desktopHeightPixels, - jdouble xdpi, jdouble ydpi, jdouble scaledDensity) + jdouble xdpi, jdouble ydpi, + jdouble scaledDensity, jdouble density) { // Android does not give us the correct screen size for immersive mode, but // the surface does have the right size @@ -558,6 +566,7 @@ static void setDisplayMetrics(JNIEnv */*env*/, jclass /*clazz*/, m_desktopWidthPixels = desktopWidthPixels; m_desktopHeightPixels = desktopHeightPixels; m_scaledDensity = scaledDensity; + m_density = density; if (!m_androidPlatformIntegration) { QAndroidPlatformIntegration::setDefaultDisplayMetrics(desktopWidthPixels, @@ -683,7 +692,7 @@ static JNINativeMethod methods[] = { {"startQtApplication", "(Ljava/lang/String;Ljava/lang/String;)V", (void *)startQtApplication}, {"quitQtAndroidPlugin", "()V", (void *)quitQtAndroidPlugin}, {"terminateQt", "()V", (void *)terminateQt}, - {"setDisplayMetrics", "(IIIIDDD)V", (void *)setDisplayMetrics}, + {"setDisplayMetrics", "(IIIIDDDD)V", (void *)setDisplayMetrics}, {"setSurface", "(ILjava/lang/Object;II)V", (void *)setSurface}, {"updateWindow", "()V", (void *)updateWindow}, {"updateApplicationState", "(I)V", (void *)updateApplicationState}, diff --git a/src/plugins/platforms/android/androidjnimain.h b/src/plugins/platforms/android/androidjnimain.h index 4d037f4b74..cdedeb38f8 100644 --- a/src/plugins/platforms/android/androidjnimain.h +++ b/src/plugins/platforms/android/androidjnimain.h @@ -71,6 +71,7 @@ namespace QtAndroid int desktopWidthPixels(); int desktopHeightPixels(); double scaledDensity(); + double pixelDensity(); JavaVM *javaVM(); AAssetManager *assetManager(); jclass applicationClass(); diff --git a/src/plugins/platforms/android/qandroidplatformscreen.cpp b/src/plugins/platforms/android/qandroidplatformscreen.cpp index 7a509e4d61..209ce2f7db 100644 --- a/src/plugins/platforms/android/qandroidplatformscreen.cpp +++ b/src/plugins/platforms/android/qandroidplatformscreen.cpp @@ -382,6 +382,11 @@ QDpi QAndroidPlatformScreen::logicalDpi() const return QDpi(lDpi, lDpi); } +qreal QAndroidPlatformScreen::pixelDensity() const +{ + return QtAndroid::pixelDensity(); +} + Qt::ScreenOrientation QAndroidPlatformScreen::orientation() const { return QAndroidPlatformIntegration::m_orientation; diff --git a/src/plugins/platforms/android/qandroidplatformscreen.h b/src/plugins/platforms/android/qandroidplatformscreen.h index 403d6036f0..1b7bc91c83 100644 --- a/src/plugins/platforms/android/qandroidplatformscreen.h +++ b/src/plugins/platforms/android/qandroidplatformscreen.h @@ -49,7 +49,6 @@ QT_BEGIN_NAMESPACE class QAndroidPlatformWindow; -class QAndroidPlatformBackingStore; class QAndroidPlatformScreen: public QObject, public QPlatformScreen, public AndroidSurfaceClient { @@ -96,6 +95,7 @@ protected: private: QDpi logicalDpi() const; + qreal pixelDensity() const; Qt::ScreenOrientation orientation() const; Qt::ScreenOrientation nativeOrientation() const; void surfaceChanged(JNIEnv *env, jobject surface, int w, int h); diff --git a/src/plugins/platforms/android/qandroidplatformservices.cpp b/src/plugins/platforms/android/qandroidplatformservices.cpp index 2dba6c78e1..412e3e0466 100644 --- a/src/plugins/platforms/android/qandroidplatformservices.cpp +++ b/src/plugins/platforms/android/qandroidplatformservices.cpp @@ -33,8 +33,9 @@ #include "qandroidplatformservices.h" #include <QUrl> -#include <QDir> +#include <QFile> #include <QDebug> +#include <QMimeDatabase> #include <QtCore/private/qjni_p.h> QT_BEGIN_NAMESPACE @@ -43,13 +44,27 @@ QAndroidPlatformServices::QAndroidPlatformServices() { } -bool QAndroidPlatformServices::openUrl(const QUrl &url) +bool QAndroidPlatformServices::openUrl(const QUrl &theUrl) { + QString mime; + QUrl url(theUrl); + + // if the file is local, we need to pass the MIME type, otherwise Android + // does not start an Intent to view this file + if ((url.scheme().isEmpty() && QFile::exists(url.path())) || url.isLocalFile()) { + // a real URL including the scheme is needed, else the Intent can not be started + url.setScheme(QLatin1String("file")); + + QMimeDatabase mimeDb; + mime = mimeDb.mimeTypeForUrl(url).name(); + } + QJNIObjectPrivate urlString = QJNIObjectPrivate::fromString(url.toString()); + QJNIObjectPrivate mimeString = QJNIObjectPrivate::fromString(mime); return QJNIObjectPrivate::callStaticMethod<jboolean>(QtAndroid::applicationClass(), "openURL", - "(Ljava/lang/String;)Z", - urlString.object()); + "(Ljava/lang/String;Ljava/lang/String;)Z", + urlString.object(), mimeString.object()); } bool QAndroidPlatformServices::openDocument(const QUrl &url) diff --git a/src/plugins/platforms/android/qandroidplatformtheme.cpp b/src/plugins/platforms/android/qandroidplatformtheme.cpp index 3e2ae7c939..71a3f910d2 100644 --- a/src/plugins/platforms/android/qandroidplatformtheme.cpp +++ b/src/plugins/platforms/android/qandroidplatformtheme.cpp @@ -31,6 +31,7 @@ ** ****************************************************************************/ +#include "androidjnimain.h" #include "androidjnimenu.h" #include "qandroidplatformtheme.h" #include "qandroidplatformmenubar.h" @@ -216,6 +217,7 @@ QJsonObject AndroidStyle::loadStyleData() static std::shared_ptr<AndroidStyle> loadAndroidStyle(QPalette *defaultPalette) { + double pixelDensity = qEnvironmentVariableIsSet("QT_AUTO_SCREEN_SCALE_FACTOR") ? QtAndroid::pixelDensity() : 1.0; std::shared_ptr<AndroidStyle> style(new AndroidStyle); style->m_styleData = AndroidStyle::loadStyleData(); if (style->m_styleData.isEmpty()) @@ -245,7 +247,7 @@ static std::shared_ptr<AndroidStyle> loadAndroidStyle(QPalette *defaultPalette) // Font size (in pixels) attributeIterator = item.find(QLatin1String("TextAppearance_textSize")); if (attributeIterator != item.constEnd()) - font.setPixelSize(int(attributeIterator.value().toDouble())); + font.setPixelSize(int(attributeIterator.value().toDouble() / pixelDensity)); // Font style attributeIterator = item.find(QLatin1String("TextAppearance_textStyle")); diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm index 050fb7ba0a..5b2ee1c284 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm +++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm @@ -56,6 +56,14 @@ static void convertLineOffset(QAccessibleTextInterface *text, int &line, int &of do { curStart = curEnd; text->textAtOffset(curStart, QAccessible::LineBoundary, &curStart, &curEnd); + // If the text is empty then we just return + if (curStart == -1 || curEnd == -1) { + if (start) + *start = 0; + if (end) + *end = 0; + return; + } ++curLine; { // check for a case where a single word longer than the text edit's width and gets wrapped diff --git a/src/plugins/platforms/cocoa/qcocoainputcontext.h b/src/plugins/platforms/cocoa/qcocoainputcontext.h index c7df823dc4..054c4795cb 100644 --- a/src/plugins/platforms/cocoa/qcocoainputcontext.h +++ b/src/plugins/platforms/cocoa/qcocoainputcontext.h @@ -35,6 +35,7 @@ #define QCOCOAINPUTCONTEXT_H #include <qpa/qplatforminputcontext.h> +#include <QtCore/QLocale> #include <QtCore/QPointer> QT_BEGIN_NAMESPACE @@ -50,12 +51,16 @@ public: void reset() Q_DECL_OVERRIDE; + QLocale locale() const Q_DECL_OVERRIDE { return m_locale; } + void updateLocale(); + private Q_SLOTS: void connectSignals(); void focusObjectChanged(QObject *focusObject); private: QPointer<QWindow> mWindow; + QLocale m_locale; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoainputcontext.mm b/src/plugins/platforms/cocoa/qcocoainputcontext.mm index f072991bdd..7d01826ffe 100644 --- a/src/plugins/platforms/cocoa/qcocoainputcontext.mm +++ b/src/plugins/platforms/cocoa/qcocoainputcontext.mm @@ -36,6 +36,8 @@ #include "qcocoanativeinterface.h" #include "qcocoawindow.h" +#include <Carbon/Carbon.h> + #include <QtCore/QRect> #include <QtGui/QGuiApplication> #include <QtGui/QWindow> @@ -76,6 +78,7 @@ QCocoaInputContext::QCocoaInputContext() , mWindow(QGuiApplication::focusWindow()) { QMetaObject::invokeMethod(this, "connectSignals", Qt::QueuedConnection); + updateLocale(); } QCocoaInputContext::~QCocoaInputContext() @@ -116,4 +119,20 @@ void QCocoaInputContext::focusObjectChanged(QObject *focusObject) mWindow = QGuiApplication::focusWindow(); } +void QCocoaInputContext::updateLocale() +{ + TISInputSourceRef source = TISCopyCurrentKeyboardInputSource(); + CFArrayRef languages = (CFArrayRef) TISGetInputSourceProperty(source, kTISPropertyInputSourceLanguages); + if (CFArrayGetCount(languages) > 0) { + CFStringRef langRef = (CFStringRef)CFArrayGetValueAtIndex(languages, 0); + QString name = QCFString::toQString(langRef); + QLocale locale(name); + if (m_locale != locale) { + m_locale = locale; + emitLocaleChanged(); + } + CFRelease(langRef); + } +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm index a59504ffaf..76406539c3 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm +++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm @@ -199,6 +199,8 @@ void QCocoaMenuItem::setEnabled(bool enabled) void QCocoaMenuItem::setNativeContents(WId item) { NSView *itemView = (NSView *)item; + if (m_itemView == itemView) + return; [m_itemView release]; m_itemView = [itemView retain]; [m_itemView setAutoresizesSubviews:YES]; @@ -303,8 +305,8 @@ NSMenuItem *QCocoaMenuItem::sync() if (!m_native) { m_native = [[NSMenuItem alloc] initWithTitle:QCFString::toNSString(m_text) - action:nil - keyEquivalent:@""]; + action:nil + keyEquivalent:@""]; [m_native setTag:reinterpret_cast<NSInteger>(this)]; } diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h index d7b9c3831b..be7602a815 100644 --- a/src/plugins/platforms/cocoa/qnsview.h +++ b/src/plugins/platforms/cocoa/qnsview.h @@ -77,6 +77,7 @@ Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper)); bool m_scrolling; bool m_exposedOnMoveToWindow; NSEvent *m_currentlyInterpretedKeyEvent; + bool m_isMenuView; } - (id)init; @@ -94,6 +95,7 @@ Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper)); - (void)notifyWindowStateChanged:(Qt::WindowState)newState; - (void)windowNotification : (NSNotification *) windowNotification; - (void)notifyWindowWillZoom:(BOOL)willZoom; +- (void)textInputContextKeyboardSelectionDidChangeNotification : (NSNotification *) textInputContextKeyboardSelectionDidChangeNotification; - (void)viewDidHide; - (void)viewDidUnhide; diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 8c22e51fe2..faa048874f 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -41,6 +41,7 @@ #include "qcocoahelpers.h" #include "qmultitouch_mac_p.h" #include "qcocoadrag.h" +#include "qcocoainputcontext.h" #include <qpa/qplatformintegration.h> #include <qpa/qwindowsysteminterface.h> @@ -160,6 +161,8 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil; touchDevice->setCapabilities(QTouchDevice::Position | QTouchDevice::NormalizedPosition | QTouchDevice::MouseEmulation); QWindowSystemInterface::registerTouchDevice(touchDevice); } + + m_isMenuView = false; } return self; } @@ -213,6 +216,11 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil; name:NSViewFrameDidChangeNotification object:self]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(textInputContextKeyboardSelectionDidChangeNotification:) + name:NSTextInputContextKeyboardSelectionDidChangeNotification + object:nil]; + return self; } @@ -269,11 +277,11 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil; - (void)viewDidMoveToWindow { + m_isMenuView = [self.window.className isEqualToString:@"NSCarbonMenuWindow"]; if (self.window) { // This is the case of QWidgetAction's generated QWidget inserted in an NSMenu. // 10.9 and newer get the NSWindowDidChangeOcclusionStateNotification - if ((!_q_NSWindowDidChangeOcclusionStateNotification - && [self.window.className isEqualToString:@"NSCarbonMenuWindow"])) { + if (!_q_NSWindowDidChangeOcclusionStateNotification && m_isMenuView) { m_exposedOnMoveToWindow = true; m_platformWindow->exposeWindow(); } @@ -402,7 +410,7 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil; NSString *notificationName = [windowNotification name]; if (notificationName == NSWindowDidBecomeKeyNotification) { - if (!m_platformWindow->windowIsPopupType()) + if (!m_platformWindow->windowIsPopupType() && !m_isMenuView) QWindowSystemInterface::handleWindowActivated(m_window); } else if (notificationName == NSWindowDidResignKeyNotification) { // key window will be non-nil if another window became key... do not @@ -411,7 +419,7 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil; NSWindow *keyWindow = [NSApp keyWindow]; if (!keyWindow) { // no new key window, go ahead and set the active window to zero - if (!m_platformWindow->windowIsPopupType()) + if (!m_platformWindow->windowIsPopupType() && !m_isMenuView) QWindowSystemInterface::handleWindowActivated(0); } } else if (notificationName == NSWindowDidMiniaturizeNotification @@ -462,6 +470,15 @@ QT_WARNING_POP } } +- (void)textInputContextKeyboardSelectionDidChangeNotification : (NSNotification *) textInputContextKeyboardSelectionDidChangeNotification +{ + Q_UNUSED(textInputContextKeyboardSelectionDidChangeNotification) + if (([NSApp keyWindow] == [self window]) && [[self window] firstResponder] == self) { + QCocoaInputContext *ic = qobject_cast<QCocoaInputContext *>(QCocoaIntegration::instance()->inputContext()); + ic->updateLocale(); + } +} + - (void)notifyWindowWillZoom:(BOOL)willZoom { Qt::WindowState newState = willZoom ? Qt::WindowMaximized : Qt::WindowNoState; @@ -621,13 +638,15 @@ QT_WARNING_POP { if (m_window && (m_window->flags() & Qt::WindowTransparentForInput) ) return NO; - if (!m_platformWindow->windowIsPopupType()) + if (!m_platformWindow->windowIsPopupType() && !m_isMenuView) QWindowSystemInterface::handleWindowActivated([self topLevelWindow]); return YES; } - (BOOL)acceptsFirstResponder { + if (m_isMenuView) + return NO; if (m_platformWindow->shouldRefuseKeyWindowAndFirstResponder()) return NO; if (m_window && (m_window->flags() & Qt::WindowTransparentForInput) ) diff --git a/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro b/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro index cf367d930f..266a97dff5 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro @@ -6,3 +6,4 @@ contains(QT_CONFIG, eglfs_egldevice): SUBDIRS += eglfs_kms_egldevice contains(QT_CONFIG, eglfs_brcm): SUBDIRS += eglfs_brcm contains(QT_CONFIG, eglfs_mali): SUBDIRS += eglfs_mali contains(QT_CONFIG, eglfs_viv): SUBDIRS += eglfs_viv +contains(QT_CONFIG, eglfs_viv_wl): SUBDIRS += eglfs_viv_wl diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/eglfs_viv_wl.json b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/eglfs_viv_wl.json new file mode 100644 index 0000000000..ced5245fa0 --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/eglfs_viv_wl.json @@ -0,0 +1,3 @@ +{ + "Keys": [ "eglfs_viv_wl" ] +} diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/eglfs_viv_wl.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/eglfs_viv_wl.pro new file mode 100644 index 0000000000..26b6a2e9ea --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/eglfs_viv_wl.pro @@ -0,0 +1,23 @@ +TARGET = qeglfs-viv-wl-integration + +PLUGIN_TYPE = egldeviceintegrations +PLUGIN_CLASS_NAME = QEglFSVivWaylandIntegrationPlugin +load(qt_plugin) + +QT += core-private gui-private platformsupport-private eglfs_device_lib-private + +INCLUDEPATH += $$PWD/../.. +CONFIG += egl +DEFINES += LINUX=1 EGL_API_FB=1 +LIBS += -lGAL +QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF + +SOURCES += $$PWD/qeglfsvivwlmain.cpp \ + $$PWD/qeglfsvivwlintegration.cpp + +HEADERS += $$PWD/qeglfsvivwlintegration.h + +OTHER_FILES += $$PWD/eglfs_viv_wl.json + +CONFIG += link_pkgconfig +PKGCONFIG_PRIVATE += wayland-server diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/qeglfsvivwlintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/qeglfsvivwlintegration.cpp new file mode 100644 index 0000000000..9eebcc772a --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/qeglfsvivwlintegration.cpp @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qeglfsvivwlintegration.h" +#include <EGL/eglvivante.h> +#include <QDebug> + +#include <wayland-server.h> + +QT_BEGIN_NAMESPACE + +void QEglFSVivWaylandIntegration::platformInit() +{ + QEGLDeviceIntegration::platformInit(); + + int width, height; + + bool multiBufferNotEnabledYet = qEnvironmentVariableIsEmpty("FB_MULTI_BUFFER"); + bool multiBuffer = qEnvironmentVariableIsEmpty("QT_EGLFS_IMX6_NO_FB_MULTI_BUFFER"); + if (multiBufferNotEnabledYet && multiBuffer) { + qWarning() << "QEglFSVivWaylandIntegration will set environment variable FB_MULTI_BUFFER=2 to enable double buffering and vsync.\n" + << "If this is not desired, you can override this via: export QT_EGLFS_IMX6_NO_FB_MULTI_BUFFER=1"; + qputenv("FB_MULTI_BUFFER", "2"); + } + + mWaylandDisplay = wl_display_create(); + mNativeDisplay = fbGetDisplay(mWaylandDisplay); + fbGetDisplayGeometry(mNativeDisplay, &width, &height); + mScreenSize.setHeight(height); + mScreenSize.setWidth(width); +} + +QSize QEglFSVivWaylandIntegration::screenSize() const +{ + return mScreenSize; +} + +EGLNativeDisplayType QEglFSVivWaylandIntegration::platformDisplay() const +{ + return mNativeDisplay; +} + +EGLNativeWindowType QEglFSVivWaylandIntegration::createNativeWindow(QPlatformWindow *window, const QSize &size, const QSurfaceFormat &format) +{ + Q_UNUSED(window) + Q_UNUSED(format) + + EGLNativeWindowType eglWindow = fbCreateWindow(mNativeDisplay, 0, 0, size.width(), size.height()); + return eglWindow; +} + +void QEglFSVivWaylandIntegration::destroyNativeWindow(EGLNativeWindowType window) +{ + fbDestroyWindow(window); +} + +void *QEglFSVivWaylandIntegration::wlDisplay() const +{ + return mWaylandDisplay; +} + + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/qeglfsvivwlintegration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/qeglfsvivwlintegration.h new file mode 100644 index 0000000000..677a1b6337 --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/qeglfsvivwlintegration.h @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QEGLFSVIVINTEGRATION_H +#define QEGLFSVIVINTEGRATION_H + +#include "qeglfsdeviceintegration.h" +struct wl_display; + +QT_BEGIN_NAMESPACE + +class QEglFSVivWaylandIntegration : public QEGLDeviceIntegration +{ +public: + void platformInit() Q_DECL_OVERRIDE; + QSize screenSize() const Q_DECL_OVERRIDE; + EGLNativeWindowType createNativeWindow(QPlatformWindow *window, const QSize &size, const QSurfaceFormat &format) Q_DECL_OVERRIDE; + void destroyNativeWindow(EGLNativeWindowType window) Q_DECL_OVERRIDE; + EGLNativeDisplayType platformDisplay() const Q_DECL_OVERRIDE; + + void *wlDisplay() const Q_DECL_OVERRIDE; +private: + QSize mScreenSize; + EGLNativeDisplayType mNativeDisplay; + wl_display *mWaylandDisplay; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/qeglfsvivwlmain.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/qeglfsvivwlmain.cpp new file mode 100644 index 0000000000..a48aa08e40 --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/qeglfsvivwlmain.cpp @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qeglfsdeviceintegration.h" +#include "qeglfsvivwlintegration.h" + +QT_BEGIN_NAMESPACE + +class QEglFSVivWaylandIntegrationPlugin : public QEGLDeviceIntegrationPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID QEGLDeviceIntegrationFactoryInterface_iid FILE "eglfs_viv_wl.json") + +public: + QEGLDeviceIntegration *create() Q_DECL_OVERRIDE { return new QEglFSVivWaylandIntegration; } +}; + +QT_END_NAMESPACE + +#include "qeglfsvivwlmain.moc" diff --git a/src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp b/src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp index 0c2aa7ad61..10c8091815 100644 --- a/src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp +++ b/src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp @@ -334,4 +334,9 @@ bool QEGLDeviceIntegration::supportsSurfacelessContexts() const return true; } +void *QEGLDeviceIntegration::wlDisplay() const +{ + return Q_NULLPTR; +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/qeglfsdeviceintegration.h b/src/plugins/platforms/eglfs/qeglfsdeviceintegration.h index d91d67de16..97082df7f5 100644 --- a/src/plugins/platforms/eglfs/qeglfsdeviceintegration.h +++ b/src/plugins/platforms/eglfs/qeglfsdeviceintegration.h @@ -97,6 +97,8 @@ public: virtual int framebufferIndex() const; virtual bool supportsPBuffers() const; virtual bool supportsSurfacelessContexts() const; + + virtual void *wlDisplay() const; }; class Q_EGLFS_EXPORT QEGLDeviceIntegrationPlugin : public QObject diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/qeglfsintegration.cpp index 2df06caa6b..2086ce56e2 100644 --- a/src/plugins/platforms/eglfs/qeglfsintegration.cpp +++ b/src/plugins/platforms/eglfs/qeglfsintegration.cpp @@ -251,7 +251,8 @@ enum ResourceType { EglContext, EglConfig, NativeDisplay, - XlibDisplay + XlibDisplay, + WaylandDisplay }; static int resourceType(const QByteArray &key) @@ -262,7 +263,8 @@ static int resourceType(const QByteArray &key) QByteArrayLiteral("eglcontext"), QByteArrayLiteral("eglconfig"), QByteArrayLiteral("nativedisplay"), - QByteArrayLiteral("display") + QByteArrayLiteral("display"), + QByteArrayLiteral("server_wl_display") }; const QByteArray *end = names + sizeof(names) / sizeof(names[0]); const QByteArray *result = std::find(names, end, key); @@ -282,6 +284,9 @@ void *QEglFSIntegration::nativeResourceForIntegration(const QByteArray &resource case NativeDisplay: result = reinterpret_cast<void*>(nativeDisplay()); break; + case WaylandDisplay: + result = qt_egl_device_integration()->wlDisplay(); + break; default: break; } diff --git a/src/plugins/platforms/mirclient/qmirclientwindow.cpp b/src/plugins/platforms/mirclient/qmirclientwindow.cpp index f3fd1e756d..3d1e5377e5 100644 --- a/src/plugins/platforms/mirclient/qmirclientwindow.cpp +++ b/src/plugins/platforms/mirclient/qmirclientwindow.cpp @@ -158,7 +158,7 @@ QMirClientWindow::QMirClientWindow(QWindow* w, QSharedPointer<QMirClientClipboar d->id = id++; // Use client geometry if set explicitly, use available screen geometry otherwise. - QPlatformWindow::setGeometry(window()->geometry() != screen->geometry() ? + QPlatformWindow::setGeometry(window()->geometry().isValid() && window()->geometry() != screen->geometry() ? window()->geometry() : screen->availableGeometry()); createWindow(); DLOG("QMirClientWindow::QMirClientWindow (this=%p, w=%p, screen=%p, input=%p)", this, w, screen, input); @@ -198,6 +198,8 @@ void QMirClientWindowPrivate::destroyEGLSurface() // we need to guess the panel height (3GU + 2DP) int QMirClientWindowPrivate::panelHeight() { + if (qEnvironmentVariableIsSet("QT_MIRCLIENT_IGNORE_PANEL")) + return 0; const int defaultGridUnit = 8; int gridUnit = defaultGridUnit; QByteArray gridUnitString = qgetenv("GRID_UNIT_PX"); diff --git a/src/plugins/platforms/windows/qwindowsclipboard.cpp b/src/plugins/platforms/windows/qwindowsclipboard.cpp index 97459a4d97..8936b96b1f 100644 --- a/src/plugins/platforms/windows/qwindowsclipboard.cpp +++ b/src/plugins/platforms/windows/qwindowsclipboard.cpp @@ -69,6 +69,7 @@ static const char formatTextHtmlC[] = "text/html"; \ingroup qt-lighthouse-win */ +#ifndef QT_NO_DEBUG_STREAM static QDebug operator<<(QDebug d, const QMimeData *mimeData) { QDebugStateSaver saver(d); @@ -93,6 +94,7 @@ static QDebug operator<<(QDebug d, const QMimeData *mimeData) d << ')'; return d; } +#endif // !QT_NO_DEBUG_STREAM /*! \class QWindowsClipboardRetrievalMimeData diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index 4d18e7ea58..02accfae01 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -201,12 +201,14 @@ void QWindowsUser32DLL::init() bool QWindowsUser32DLL::initTouch() { - QSystemLibrary library(QStringLiteral("user32")); - isTouchWindow = (IsTouchWindow)(library.resolve("IsTouchWindow")); - registerTouchWindow = (RegisterTouchWindow)(library.resolve("RegisterTouchWindow")); - unregisterTouchWindow = (UnregisterTouchWindow)(library.resolve("UnregisterTouchWindow")); - getTouchInputInfo = (GetTouchInputInfo)(library.resolve("GetTouchInputInfo")); - closeTouchInputHandle = (CloseTouchInputHandle)(library.resolve("CloseTouchInputHandle")); + if (!isTouchWindow && QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS7) { + QSystemLibrary library(QStringLiteral("user32")); + isTouchWindow = (IsTouchWindow)(library.resolve("IsTouchWindow")); + registerTouchWindow = (RegisterTouchWindow)(library.resolve("RegisterTouchWindow")); + unregisterTouchWindow = (UnregisterTouchWindow)(library.resolve("UnregisterTouchWindow")); + getTouchInputInfo = (GetTouchInputInfo)(library.resolve("GetTouchInputInfo")); + closeTouchInputHandle = (CloseTouchInputHandle)(library.resolve("CloseTouchInputHandle")); + } return isTouchWindow && registerTouchWindow && unregisterTouchWindow && getTouchInputInfo && closeTouchInputHandle; } @@ -359,6 +361,36 @@ QWindowsContext::~QWindowsContext() m_instance = 0; } +bool QWindowsContext::initTouch() +{ + return initTouch(QWindowsIntegration::instance()->options()); +} + +bool QWindowsContext::initTouch(unsigned integrationOptions) +{ + if (d->m_systemInfo & QWindowsContext::SI_SupportsTouch) + return true; + + QTouchDevice *touchDevice = d->m_mouseHandler.ensureTouchDevice(); + if (!touchDevice) + return false; + +#ifndef Q_OS_WINCE + if (!QWindowsContext::user32dll.initTouch()) { + delete touchDevice; + return false; + } +#endif // !Q_OS_WINCE + + if (!(integrationOptions & QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch)) + touchDevice->setCapabilities(touchDevice->capabilities() | QTouchDevice::MouseEmulation); + + QWindowSystemInterface::registerTouchDevice(touchDevice); + + d->m_systemInfo |= QWindowsContext::SI_SupportsTouch; + return true; +} + void QWindowsContext::setTabletAbsoluteRange(int a) { #if !defined(QT_NO_TABLETEVENT) && !defined(Q_OS_WINCE) diff --git a/src/plugins/platforms/windows/qwindowscontext.h b/src/plugins/platforms/windows/qwindowscontext.h index d2a3481b28..641e3ed41f 100644 --- a/src/plugins/platforms/windows/qwindowscontext.h +++ b/src/plugins/platforms/windows/qwindowscontext.h @@ -170,6 +170,9 @@ public: explicit QWindowsContext(); ~QWindowsContext(); + bool initTouch(); + bool initTouch(unsigned integrationOptions); // For calls from QWindowsIntegration::QWindowsIntegration() only. + int defaultDPI() const; QString registerWindowClass(const QWindow *w); diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp index da0ba27e3a..b983ba3354 100644 --- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp +++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp @@ -360,6 +360,7 @@ public: QT_BEGIN_NAMESPACE +#ifndef QT_NO_DEBUG_STREAM /* Output UID (IID, CLSID) as C++ constants. * The constants are contained in the Windows SDK libs, but not for MinGW. */ static inline QString guidToString(const GUID &g) @@ -385,6 +386,7 @@ inline QDebug operator<<(QDebug d, const GUID &g) d << guidToString(g); return d; } +#endif // !QT_NO_DEBUG_STREAM // Return an allocated wchar_t array from a QString, reserve more memory if desired. static wchar_t *qStringToWCharArray(const QString &s, size_t reserveSize = 0) diff --git a/src/plugins/platforms/windows/qwindowsdrag.cpp b/src/plugins/platforms/windows/qwindowsdrag.cpp index 719553fa7c..fcd9911a56 100644 --- a/src/plugins/platforms/windows/qwindowsdrag.cpp +++ b/src/plugins/platforms/windows/qwindowsdrag.cpp @@ -247,7 +247,7 @@ private: QWindowsDragCursorWindow *m_touchDragWindow; ULONG m_refs; -#ifndef QT_NO_DEBUG_OUTPUT +#ifndef QT_NO_DEBUG_STREAM friend QDebug operator<<(QDebug, const QWindowsOleDropSource::CursorEntry &); #endif }; @@ -269,14 +269,14 @@ QWindowsOleDropSource::~QWindowsOleDropSource() qCDebug(lcQpaMime) << __FUNCTION__; } -#ifndef QT_NO_DEBUG_OUTPUT +#ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug d, const QWindowsOleDropSource::CursorEntry &e) { d << "CursorEntry:" << e.pixmap.size() << '#' << e.cacheKey << "HCURSOR" << e.cursor->cursor << "hotspot:" << e.hotSpot; return d; } -#endif // !QT_NO_DEBUG_OUTPUT +#endif // !QT_NO_DEBUG_STREAM static qreal dragScaleFactor() { diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp index eb8262262f..a30e545807 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp @@ -40,6 +40,7 @@ #include <QtGui/QFont> #include <QtGui/QGuiApplication> +#include <QtGui/private/qhighdpiscaling_p.h> #include <QtCore/qmath.h> #include <QtCore/QDebug> @@ -607,6 +608,7 @@ static inline bool initDirectWrite(QWindowsFontEngineData *d) \ingroup qt-lighthouse-win */ +#ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug d, const QFontDef &def) { QDebugStateSaver saver(d); @@ -618,6 +620,7 @@ QDebug operator<<(QDebug d, const QFontDef &def) << def.hintingPreference; return d; } +#endif // !QT_NO_DEBUG_STREAM static inline QFontDatabase::WritingSystem writingSystemFromCharSet(uchar charSet) { @@ -1099,8 +1102,11 @@ QFontEngine *QWindowsFontDatabase::fontEngine(const QByteArray &fontData, qreal QFontEngine *fontEngine = 0; #if !defined(QT_NO_DIRECTWRITE) - if (hintingPreference == QFont::PreferDefaultHinting - || hintingPreference == QFont::PreferFullHinting) + bool useDirectWrite = (hintingPreference == QFont::PreferNoHinting) + || (hintingPreference == QFont::PreferVerticalHinting) + || (QHighDpiScaling::isActive() && hintingPreference == QFont::PreferDefaultHinting); + + if (!useDirectWrite) #endif { GUID guid; @@ -1703,7 +1709,8 @@ QFontEngine *QWindowsFontDatabase::createEngine(const QFontDef &request, #if !defined(QT_NO_DIRECTWRITE) bool useDirectWrite = (request.hintingPreference == QFont::PreferNoHinting) - || (request.hintingPreference == QFont::PreferVerticalHinting); + || (request.hintingPreference == QFont::PreferVerticalHinting) + || (QHighDpiScaling::isActive() && request.hintingPreference == QFont::PreferDefaultHinting); if (useDirectWrite && initDirectWrite(data.data())) { const QString fam = QString::fromWCharArray(lf.lfFaceName); const QString nameSubstitute = QWindowsFontEngineDirectWrite::fontNameSubstitute(fam); diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.h b/src/plugins/platforms/windows/qwindowsfontdatabase.h index efb5421996..10b6315aab 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase.h +++ b/src/plugins/platforms/windows/qwindowsfontdatabase.h @@ -118,6 +118,10 @@ private: QMap<QString, UniqueFontData> m_uniqueFontData; }; +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug, const QFontDef &def); +#endif + QT_END_NAMESPACE #endif // QWINDOWSFONTDATABASE_H diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp index d827607bc5..361e7f4445 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp @@ -353,7 +353,7 @@ static bool addFontToDatabase(const QString &faceName, const QFont::Weight weight = QPlatformFontDatabase::weightFromInteger(tm->tmWeight); const QFont::Stretch stretch = QFont::Unstretched; -#ifndef QT_NO_DEBUG_OUTPUT +#ifndef QT_NO_DEBUG_STREAM if (QWindowsContext::verbose > 2) { QString message; QTextStream str(&message); diff --git a/src/plugins/platforms/windows/qwindowsglcontext.cpp b/src/plugins/platforms/windows/qwindowsglcontext.cpp index e372acc747..a06707b84c 100644 --- a/src/plugins/platforms/windows/qwindowsglcontext.cpp +++ b/src/plugins/platforms/windows/qwindowsglcontext.cpp @@ -284,6 +284,7 @@ static inline void initPixelFormatDescriptor(PIXELFORMATDESCRIPTOR *d) d->nVersion = 1; } +#ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug d, const PIXELFORMATDESCRIPTOR &pd) { QDebugStateSaver saver(d); @@ -326,6 +327,32 @@ QDebug operator<<(QDebug d, const PIXELFORMATDESCRIPTOR &pd) return d; } +QDebug operator<<(QDebug d, const QOpenGLStaticContext &s) +{ + QDebugStateSaver saver(d); + d.nospace(); + d << "OpenGL: " << s.vendor << ',' << s.renderer << " default " + << s.defaultFormat; + if (s.extensions & QOpenGLStaticContext::SampleBuffers) + d << ",SampleBuffers"; + if (s.hasExtensions()) + d << ", Extension-API present"; + d << "\nExtensions: " << (s.extensionNames.count(' ') + 1); + if (QWindowsContext::verbose > 1) + d << s.extensionNames; + return d; +} + +QDebug operator<<(QDebug d, const QWindowsOpenGLContextFormat &f) +{ + QDebugStateSaver saver(d); + d.nospace(); + d << "ContextFormat: v" << (f.version >> 8) << '.' << (f.version & 0xFF) + << " profile: " << f.profile << " options: " << f.options; + return d; +} +#endif // !QT_NO_DEBUG_STREAM + // Check whether an obtained PIXELFORMATDESCRIPTOR matches the request. static inline bool isAcceptableFormat(const QWindowsOpenGLAdditionalFormat &additional, @@ -900,15 +927,6 @@ void QWindowsOpenGLContextFormat::apply(QSurfaceFormat *format) const format->setOption(QSurfaceFormat::DeprecatedFunctions); } -QDebug operator<<(QDebug d, const QWindowsOpenGLContextFormat &f) -{ - QDebugStateSaver saver(d); - d.nospace(); - d << "ContextFormat: v" << (f.version >> 8) << '.' << (f.version & 0xFF) - << " profile: " << f.profile << " options: " << f.options; - return d; -} - /*! \class QOpenGLTemporaryContext \brief A temporary context that can be instantiated on the stack. @@ -1013,22 +1031,6 @@ QOpenGLStaticContext *QOpenGLStaticContext::create(bool softwareRendering) return result; } -QDebug operator<<(QDebug d, const QOpenGLStaticContext &s) -{ - QDebugStateSaver saver(d); - d.nospace(); - d << "OpenGL: " << s.vendor << ',' << s.renderer << " default " - << s.defaultFormat; - if (s.extensions & QOpenGLStaticContext::SampleBuffers) - d << ",SampleBuffers"; - if (s.hasExtensions()) - d << ", Extension-API present"; - d << "\nExtensions: " << (s.extensionNames.count(' ') + 1); - if (QWindowsContext::verbose > 1) - d << s.extensionNames; - return d; -} - /*! \class QWindowsGLContext \brief Open GL context. diff --git a/src/plugins/platforms/windows/qwindowsglcontext.h b/src/plugins/platforms/windows/qwindowsglcontext.h index 516fa0707e..ba617f13ce 100644 --- a/src/plugins/platforms/windows/qwindowsglcontext.h +++ b/src/plugins/platforms/windows/qwindowsglcontext.h @@ -85,7 +85,11 @@ struct QWindowsOpenGLContextFormat QSurfaceFormat::FormatOptions options; }; +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug d, const PIXELFORMATDESCRIPTOR &); QDebug operator<<(QDebug d, const QWindowsOpenGLContextFormat &); +QDebug operator<<(QDebug d, const QOpenGLStaticContext &s); +#endif struct QWindowsOpengl32DLL { @@ -224,8 +228,6 @@ public: static QWindowsOpengl32DLL opengl32; }; -QDebug operator<<(QDebug d, const QOpenGLStaticContext &); - class QWindowsGLContext : public QWindowsOpenGLContext { public: diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp index 7322af95d1..2f61baa8a1 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.cpp +++ b/src/plugins/platforms/windows/qwindowsintegration.cpp @@ -229,17 +229,7 @@ QWindowsIntegrationPrivate::QWindowsIntegrationPrivate(const QStringList ¶mL dpiAwarenessSet = true; } - QTouchDevice *touchDevice = m_context.touchDevice(); - if (touchDevice) { -#ifdef Q_OS_WINCE - touchDevice->setCapabilities(touchDevice->capabilities() | QTouchDevice::MouseEmulation); -#else - if (!(m_options & QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch)) { - touchDevice->setCapabilities(touchDevice->capabilities() | QTouchDevice::MouseEmulation); - } -#endif - QWindowSystemInterface::registerTouchDevice(touchDevice); - } + m_context.initTouch(m_options); } QWindowsIntegrationPrivate::~QWindowsIntegrationPrivate() diff --git a/src/plugins/platforms/windows/qwindowsmime.cpp b/src/plugins/platforms/windows/qwindowsmime.cpp index 52a4ca26dc..0a2ba9b0e7 100644 --- a/src/plugins/platforms/windows/qwindowsmime.cpp +++ b/src/plugins/platforms/windows/qwindowsmime.cpp @@ -378,7 +378,7 @@ static bool canGetData(int cf, IDataObject * pDataObj) return true; } -#ifndef QT_NO_DEBUG_OUTPUT +#ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug d, const FORMATETC &tc) { QDebugStateSaver saver(d); @@ -443,7 +443,7 @@ QDebug operator<<(QDebug d, IDataObject *dataObj) d << ')'; return d; } -#endif // !QT_NO_DEBUG_OUTPUT +#endif // !QT_NO_DEBUG_STREAM /*! \class QWindowsMime diff --git a/src/plugins/platforms/windows/qwindowsmime.h b/src/plugins/platforms/windows/qwindowsmime.h index 17fddef1bc..1ec0dccdf8 100644 --- a/src/plugins/platforms/windows/qwindowsmime.h +++ b/src/plugins/platforms/windows/qwindowsmime.h @@ -93,7 +93,7 @@ private: mutable int m_internalMimeCount; }; -#ifndef QT_NO_DEBUG_OUTPUT +#ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug, const FORMATETC &); QDebug operator<<(QDebug d, IDataObject *); #endif diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.cpp b/src/plugins/platforms/windows/qwindowsmousehandler.cpp index bd801edc4f..80f3d3e2b8 100644 --- a/src/plugins/platforms/windows/qwindowsmousehandler.cpp +++ b/src/plugins/platforms/windows/qwindowsmousehandler.cpp @@ -151,12 +151,19 @@ static inline QTouchDevice *createTouchDevice() QWindowsMouseHandler::QWindowsMouseHandler() : m_windowUnderMouse(0), m_trackedWindow(0), - m_touchDevice(createTouchDevice()), + m_touchDevice(Q_NULLPTR), m_leftButtonDown(false), m_previousCaptureWindow(0) { } +QTouchDevice *QWindowsMouseHandler::ensureTouchDevice() +{ + if (!m_touchDevice) + m_touchDevice = createTouchDevice(); + return m_touchDevice; +} + Qt::MouseButtons QWindowsMouseHandler::queryMouseButtons() { Qt::MouseButtons result = 0; @@ -477,7 +484,11 @@ bool QWindowsMouseHandler::translateTouchEvent(QWindow *window, HWND, typedef QWindowSystemInterface::TouchPoint QTouchPoint; typedef QList<QWindowSystemInterface::TouchPoint> QTouchPointList; - Q_ASSERT(m_touchDevice); + if (!QWindowsContext::instance()->initTouch()) { + qWarning("Unable to initialize touch handling."); + return true; + } + const QScreen *screen = window->screen(); if (!screen) screen = QGuiApplication::primaryScreen(); @@ -493,8 +504,6 @@ bool QWindowsMouseHandler::translateTouchEvent(QWindow *window, HWND, touchPoints.reserve(winTouchPointCount); Qt::TouchPointStates allStates = 0; - Q_ASSERT(QWindowsContext::user32dll.getTouchInputInfo); - QWindowsContext::user32dll.getTouchInputInfo((HANDLE) msg.lParam, msg.wParam, winTouchInputs.data(), sizeof(TOUCHINPUT)); for (int i = 0; i < winTouchPointCount; ++i) { const TOUCHINPUT &winTouchInput = winTouchInputs[i]; diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.h b/src/plugins/platforms/windows/qwindowsmousehandler.h index 61aa8d6084..4b5078567d 100644 --- a/src/plugins/platforms/windows/qwindowsmousehandler.h +++ b/src/plugins/platforms/windows/qwindowsmousehandler.h @@ -52,6 +52,7 @@ public: QWindowsMouseHandler(); QTouchDevice *touchDevice() const { return m_touchDevice; } + QTouchDevice *ensureTouchDevice(); bool translateMouseEvent(QWindow *widget, HWND hwnd, QtWindows::WindowsEventType t, MSG msg, diff --git a/src/plugins/platforms/windows/qwindowsopengltester.cpp b/src/plugins/platforms/windows/qwindowsopengltester.cpp index befd06f1a2..e32a7e32af 100644 --- a/src/plugins/platforms/windows/qwindowsopengltester.cpp +++ b/src/plugins/platforms/windows/qwindowsopengltester.cpp @@ -98,6 +98,7 @@ GpuDescription GpuDescription::detect() #endif } +#ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug d, const GpuDescription &gd) { QDebugStateSaver s(d); @@ -109,6 +110,7 @@ QDebug operator<<(QDebug d, const GpuDescription &gd) << ", version=" << gd.driverVersion << ", " << gd.description << ')'; return d; } +#endif // !QT_NO_DEBUG_STREAM // Return printable string formatted like the output of the dxdiag tool. QString GpuDescription::toString() const diff --git a/src/plugins/platforms/windows/qwindowsopengltester.h b/src/plugins/platforms/windows/qwindowsopengltester.h index 3cd8bf4d4b..f22031aa4e 100644 --- a/src/plugins/platforms/windows/qwindowsopengltester.h +++ b/src/plugins/platforms/windows/qwindowsopengltester.h @@ -60,7 +60,9 @@ struct GpuDescription QByteArray description; }; +#ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug d, const GpuDescription &gd); +#endif class QWindowsOpenGLTester { diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp index e6abfb2403..de4ef79b81 100644 --- a/src/plugins/platforms/windows/qwindowsscreen.cpp +++ b/src/plugins/platforms/windows/qwindowsscreen.cpp @@ -172,6 +172,7 @@ static inline WindowsScreenDataList monitorData() return result; } +#ifndef QT_NO_DEBUG_STREAM static QDebug operator<<(QDebug dbg, const QWindowsScreenData &d) { QDebugStateSaver saver(dbg); @@ -192,6 +193,7 @@ static QDebug operator<<(QDebug dbg, const QWindowsScreenData &d) dbg << " lock screen"; return dbg; } +#endif // !QT_NO_DEBUG_STREAM // Return the cursor to be shared by all screens (virtual desktop). static inline QSharedPointer<QPlatformCursor> sharedCursor() @@ -278,8 +280,11 @@ QWindow *QWindowsScreen::windowAt(const QPoint &screenPoint, unsigned flags) qreal QWindowsScreen::pixelDensity() const { - const qreal physicalDpi = m_data.geometry.width() / m_data.physicalSizeMM.width() * qreal(25.4); - return qRound(physicalDpi / 96); + // 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 qRound(logicalDpi().first / 96); } /*! diff --git a/src/plugins/platforms/windows/qwindowstabletsupport.cpp b/src/plugins/platforms/windows/qwindowstabletsupport.cpp index 3951401273..b27811df9e 100644 --- a/src/plugins/platforms/windows/qwindowstabletsupport.cpp +++ b/src/plugins/platforms/windows/qwindowstabletsupport.cpp @@ -302,8 +302,11 @@ static inline QTabletEvent::PointerType pointerType(unsigned currentCursor) return QTabletEvent::UnknownPointer; } +#ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug d, const QWindowsTabletDeviceData &t) { + QDebugStateSaver saver(d); + d.nospace(); d << "TabletDevice id:" << t.uniqueId << " pressure: " << t.minPressure << ".." << t.maxPressure << " tan pressure: " << t.minTanPressure << ".." << t.maxTanPressure << " area:" << t.minX << t.minY <<t.minZ @@ -311,6 +314,7 @@ QDebug operator<<(QDebug d, const QWindowsTabletDeviceData &t) << " pointer " << t.currentPointerType; return d; } +#endif // !QT_NO_DEBUG_STREAM QWindowsTabletDeviceData QWindowsTabletSupport::tabletInit(const quint64 uniqueId, const UINT cursorType) const { diff --git a/src/plugins/platforms/windows/qwindowstabletsupport.h b/src/plugins/platforms/windows/qwindowstabletsupport.h index 718ae98572..a6d2771206 100644 --- a/src/plugins/platforms/windows/qwindowstabletsupport.h +++ b/src/plugins/platforms/windows/qwindowstabletsupport.h @@ -97,7 +97,9 @@ struct QWindowsTabletDeviceData int currentPointerType; }; +#ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug d, const QWindowsTabletDeviceData &t); +#endif class QWindowsTabletSupport { diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 5cb34e7fd3..01e2a804bd 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -106,20 +106,6 @@ static QByteArray debugWinExStyle(DWORD exStyle) return rc; } -#ifndef Q_OS_WINCE // maybe available on some SDKs revisit WM_GETMINMAXINFO -QDebug operator<<(QDebug d, const MINMAXINFO &i) -{ - QDebugStateSaver saver(d); - d.nospace(); - d << "MINMAXINFO maxSize=" << i.ptMaxSize.x << ',' - << i.ptMaxSize.y << " maxpos=" << i.ptMaxPosition.x - << ',' << i.ptMaxPosition.y << " mintrack=" - << i.ptMinTrackSize.x << ',' << i.ptMinTrackSize.y - << " maxtrack=" << i.ptMaxTrackSize.x << ',' << i.ptMaxTrackSize.y; - return d; -} -#endif // !Q_OS_WINCE - static inline QSize qSizeOfRect(const RECT &rect) { return QSize(rect.right -rect.left, rect.bottom - rect.top); @@ -138,6 +124,7 @@ static inline RECT RECTfromQRect(const QRect &rect) return result; } +#ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug d, const RECT &r) { QDebugStateSaver saver(d); @@ -147,7 +134,13 @@ QDebug operator<<(QDebug d, const RECT &r) return d; } -#ifndef Q_OS_WINCE // maybe available on some SDKs revisit WM_NCCALCSIZE +QDebug operator<<(QDebug d, const POINT &p) +{ + d << p.x << ',' << p.y; + return d; +} + +# ifndef Q_OS_WINCE QDebug operator<<(QDebug d, const NCCALCSIZE_PARAMS &p) { QDebugStateSaver saver(d); @@ -156,7 +149,30 @@ QDebug operator<<(QDebug d, const NCCALCSIZE_PARAMS &p) << ' ' << qrectFromRECT(p.rgrc[1]) << ' ' << qrectFromRECT(p.rgrc[2]); return d; } -#endif // !Q_OS_WINCE + +QDebug operator<<(QDebug d, const MINMAXINFO &i) +{ + QDebugStateSaver saver(d); + d.nospace(); + d << "MINMAXINFO maxSize=" << i.ptMaxSize.x << ',' + << i.ptMaxSize.y << " maxpos=" << i.ptMaxPosition.x + << ',' << i.ptMaxPosition.y << " mintrack=" + << i.ptMinTrackSize.x << ',' << i.ptMinTrackSize.y + << " maxtrack=" << i.ptMaxTrackSize.x << ',' << i.ptMaxTrackSize.y; + return d; +} + +QDebug operator<<(QDebug d, const WINDOWPLACEMENT &wp) +{ + QDebugStateSaver saver(d); + d.nospace(); + d << "WINDOWPLACEMENT(flags=0x" << hex << wp.flags << dec << ", showCmd=" + << wp.showCmd << ", ptMinPosition=" << wp.ptMinPosition << ", ptMaxPosition=" << wp.ptMaxPosition + << ", rcNormalPosition=" << wp.rcNormalPosition; + return d; +} +# endif // !Q_OS_WINCE +#endif // !QT_NO_DEBUG_STREAM // QTBUG-43872, for windows that do not have WS_EX_TOOLWINDOW set, WINDOWPLACEMENT // is in workspace/available area coordinates. diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h index c73c8ca8f3..583d3a4267 100644 --- a/src/plugins/platforms/windows/qwindowswindow.h +++ b/src/plugins/platforms/windows/qwindowswindow.h @@ -290,12 +290,15 @@ private: void *m_surface; }; -// Debug +#ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug d, const RECT &r); -#ifndef Q_OS_WINCE // maybe available on some SDKs revisit WM_GETMINMAXINFO/WM_NCCALCSIZE +QDebug operator<<(QDebug d, const POINT &); +# ifndef Q_OS_WINCE QDebug operator<<(QDebug d, const MINMAXINFO &i); QDebug operator<<(QDebug d, const NCCALCSIZE_PARAMS &p); -#endif +QDebug operator<<(QDebug d, const WINDOWPLACEMENT &); +# endif // !Q_OS_WINCE +#endif // !QT_NO_DEBUG_STREAM // ---------- QWindowsGeometryHint inline functions. QPoint QWindowsGeometryHint::mapToGlobal(HWND hwnd, const QPoint &qp) diff --git a/src/plugins/platforms/winrt/qwinrtbackingstore.cpp b/src/plugins/platforms/winrt/qwinrtbackingstore.cpp index dcf8239538..4517200a2d 100644 --- a/src/plugins/platforms/winrt/qwinrtbackingstore.cpp +++ b/src/plugins/platforms/winrt/qwinrtbackingstore.cpp @@ -42,8 +42,8 @@ #include <QtGui/QOpenGLContext> #include <QtGui/QOpenGLFramebufferObject> -#include <GLES3/gl3.h> -#include <GLES3/gl3ext.h> +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> QT_BEGIN_NAMESPACE @@ -66,7 +66,8 @@ QWinRTBackingStore::QWinRTBackingStore(QWindow *window) d->initialized = false; d->screen = static_cast<QWinRTScreen*>(window->screen()->handle()); - window->setSurfaceType(QSurface::OpenGLSurface); // Required for flipping, but could be done in the swap + if (window->surfaceType() == QSurface::RasterSurface) + window->setSurfaceType(QSurface::OpenGLSurface); } bool QWinRTBackingStore::initialize() @@ -78,7 +79,6 @@ bool QWinRTBackingStore::initialize() d->context.reset(new QOpenGLContext); QSurfaceFormat format = window()->requestedFormat(); - format.setVersion(3, 0); // Required for ES3 framebuffer blit d->context->setFormat(format); d->context->setScreen(window()->screen()); if (!d->context->create()) @@ -121,13 +121,13 @@ void QWinRTBackingStore::flush(QWindow *window, const QRegion ®ion, const QPo GL_RGBA, GL_UNSIGNED_BYTE, d->paintDevice.constScanLine(bounds.y())); glBindTexture(GL_TEXTURE_2D, 0); - glBindFramebuffer(GL_READ_FRAMEBUFFER, d->fbo->handle()); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, d->fbo->handle()); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, 0); const int y1 = bounds.y(); const int y2 = y1 + bounds.height(); const int x1 = bounds.x(); const int x2 = x1 + bounds.width(); - glBlitFramebuffer(x1, y1, x2, y2, + glBlitFramebufferANGLE(x1, y1, x2, y2, x1, d->size.height() - y1, x2, d->size.height() - y2, GL_COLOR_BUFFER_BIT, GL_NEAREST); diff --git a/src/plugins/platforms/winrt/qwinrteglcontext.cpp b/src/plugins/platforms/winrt/qwinrteglcontext.cpp index 9cb45336d6..3fd0278360 100644 --- a/src/plugins/platforms/winrt/qwinrteglcontext.cpp +++ b/src/plugins/platforms/winrt/qwinrteglcontext.cpp @@ -40,6 +40,8 @@ #include <functional> +#include <d3d11.h> + #include <EGL/egl.h> #define EGL_EGLEXT_PROTOTYPES #include <EGL/eglext.h> @@ -49,13 +51,30 @@ QT_BEGIN_NAMESPACE +struct WinRTEGLDisplay +{ + WinRTEGLDisplay() { + eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); + if (eglDisplay == EGL_NO_DISPLAY) + qCritical("Failed to initialize EGL display: 0x%x", eglGetError()); + } + ~WinRTEGLDisplay() { + eglTerminate(eglDisplay); + } + + EGLDisplay eglDisplay; +}; + +Q_GLOBAL_STATIC(WinRTEGLDisplay, g) + class QWinRTEGLContextPrivate { public: + QWinRTEGLContextPrivate() : eglContext(EGL_NO_CONTEXT), eglShareContext(EGL_NO_CONTEXT) { } QSurfaceFormat format; - EGLDisplay eglDisplay; EGLConfig eglConfig; EGLContext eglContext; + EGLContext eglShareContext; }; QWinRTEGLContext::QWinRTEGLContext(QOpenGLContext *context) @@ -64,30 +83,44 @@ QWinRTEGLContext::QWinRTEGLContext(QOpenGLContext *context) Q_D(QWinRTEGLContext); d->format = context->format(); d->format.setRenderableType(QSurfaceFormat::OpenGLES); + if (QPlatformOpenGLContext *shareHandle = context->shareHandle()) + d->eglShareContext = static_cast<QWinRTEGLContext *>(shareHandle)->d_ptr->eglContext; } QWinRTEGLContext::~QWinRTEGLContext() { Q_D(QWinRTEGLContext); if (d->eglContext != EGL_NO_CONTEXT) - eglDestroyContext(d->eglDisplay, d->eglContext); - if (d->eglDisplay != EGL_NO_DISPLAY) - eglTerminate(d->eglDisplay); + eglDestroyContext(g->eglDisplay, d->eglContext); } void QWinRTEGLContext::initialize() { Q_D(QWinRTEGLContext); + // Test if the hardware supports at least level 9_3 + D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_9_3 }; // minimum feature level + HRESULT hr = D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, featureLevels, 1, + D3D11_SDK_VERSION, nullptr, nullptr, nullptr); + EGLint deviceType = SUCCEEDED(hr) ? EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE + : EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE; + eglBindAPI(EGL_OPENGL_ES_API); - d->eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); - if (d->eglDisplay == EGL_NO_DISPLAY) + + const EGLint displayAttributes[] = { + EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, + EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, deviceType, + EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, true, + EGL_NONE, + }; + g->eglDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, displayAttributes); + if (g->eglDisplay == EGL_NO_DISPLAY) qCritical("Failed to initialize EGL display: 0x%x", eglGetError()); - if (!eglInitialize(d->eglDisplay, nullptr, nullptr)) + if (!eglInitialize(g->eglDisplay, nullptr, nullptr)) qCritical("Failed to initialize EGL: 0x%x", eglGetError()); - d->eglConfig = q_configFromGLFormat(d->eglDisplay, d->format); + d->eglConfig = q_configFromGLFormat(g->eglDisplay, d->format); const EGLint flags = d->format.testOption(QSurfaceFormat::DebugContext) ? EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR : 0; @@ -97,7 +130,7 @@ void QWinRTEGLContext::initialize() EGL_CONTEXT_FLAGS_KHR, flags, EGL_NONE }; - d->eglContext = eglCreateContext(d->eglDisplay, d->eglConfig, nullptr, attributes); + d->eglContext = eglCreateContext(g->eglDisplay, d->eglConfig, d->eglShareContext, attributes); if (d->eglContext == EGL_NO_CONTEXT) { qWarning("QEGLPlatformContext: Failed to create context: %x", eglGetError()); return; @@ -107,41 +140,40 @@ void QWinRTEGLContext::initialize() bool QWinRTEGLContext::makeCurrent(QPlatformSurface *windowSurface) { Q_D(QWinRTEGLContext); - Q_ASSERT(windowSurface->surface()->surfaceType() == QSurface::OpenGLSurface); + Q_ASSERT(windowSurface->surface()->supportsOpenGL()); QWinRTWindow *window = static_cast<QWinRTWindow *>(windowSurface); if (window->eglSurface() == EGL_NO_SURFACE) - window->createEglSurface(d->eglDisplay, d->eglConfig); + window->createEglSurface(g->eglDisplay, d->eglConfig); EGLSurface surface = window->eglSurface(); if (surface == EGL_NO_SURFACE) return false; - const bool ok = eglMakeCurrent(d->eglDisplay, surface, surface, d->eglContext); + const bool ok = eglMakeCurrent(g->eglDisplay, surface, surface, d->eglContext); if (!ok) { qWarning("QEGLPlatformContext: eglMakeCurrent failed: %x", eglGetError()); return false; } - eglSwapInterval(d->eglDisplay, d->format.swapInterval()); + eglSwapInterval(g->eglDisplay, d->format.swapInterval()); return true; } void QWinRTEGLContext::doneCurrent() { - Q_D(const QWinRTEGLContext); - const bool ok = eglMakeCurrent(d->eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + const bool ok = eglMakeCurrent(g->eglDisplay, EGL_NO_SURFACE, + EGL_NO_SURFACE, EGL_NO_CONTEXT); if (!ok) qWarning("QEGLPlatformContext: eglMakeCurrent failed: %x", eglGetError()); } void QWinRTEGLContext::swapBuffers(QPlatformSurface *windowSurface) { - Q_D(QWinRTEGLContext); - Q_ASSERT(windowSurface->surface()->surfaceType() == QSurface::OpenGLSurface); + Q_ASSERT(windowSurface->surface()->supportsOpenGL()); const QWinRTWindow *window = static_cast<QWinRTWindow *>(windowSurface); - eglSwapBuffers(d->eglDisplay, window->eglSurface()); + eglSwapBuffers(g->eglDisplay, window->eglSurface()); } QSurfaceFormat QWinRTEGLContext::format() const diff --git a/src/plugins/platforms/winrt/qwinrtintegration.cpp b/src/plugins/platforms/winrt/qwinrtintegration.cpp index 7ee3bf8593..23bb6c16ec 100644 --- a/src/plugins/platforms/winrt/qwinrtintegration.cpp +++ b/src/plugins/platforms/winrt/qwinrtintegration.cpp @@ -134,10 +134,10 @@ QWinRTIntegration::QWinRTIntegration() : d_ptr(new QWinRTIntegrationPrivate) QEventDispatcherWinRT::runOnXamlThread([d]() { d->mainScreen = new QWinRTScreen; + d->inputContext.reset(new QWinRTInputContext(d->mainScreen)); return S_OK; }); - d->inputContext.reset(new QWinRTInputContext(d->mainScreen)); screenAdded(d->mainScreen); d->platformServices = new QWinRTServices; } @@ -188,6 +188,7 @@ bool QWinRTIntegration::hasCapability(QPlatformIntegration::Capability cap) cons case ApplicationState: case NonFullScreenWindows: case MultipleWindows: + case RasterGLSurface: return true; default: return QPlatformIntegration::hasCapability(cap); diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp index 0fe3262398..8ba71d88e7 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.cpp +++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp @@ -89,6 +89,27 @@ typedef ITypedEventHandler<StatusBar*, IInspectable*> StatusBarHandler; QT_BEGIN_NAMESPACE +struct KeyInfo { + KeyInfo() + : virtualKey(0) + { + } + + KeyInfo(const QString &text, quint32 virtualKey) + : text(text) + , virtualKey(virtualKey) + { + } + + KeyInfo(quint32 virtualKey) + : virtualKey(virtualKey) + { + } + + QString text; + quint32 virtualKey; +}; + static inline Qt::ScreenOrientations qtOrientationsFromNative(DisplayOrientations native) { Qt::ScreenOrientations orientations = Qt::PrimaryOrientation; @@ -435,10 +456,7 @@ public: Qt::ScreenOrientation nativeOrientation; Qt::ScreenOrientation orientation; QList<QWindow *> visibleWindows; -#ifndef Q_OS_WINPHONE - QHash<quint32, QPair<Qt::Key, QString>> activeKeys; -#endif - + QHash<Qt::Key, KeyInfo> activeKeys; QHash<CoreWindowCallbackRemover, EventRegistrationToken> windowTokens; QHash<DisplayCallbackRemover, EventRegistrationToken> displayTokens; #ifdef Q_OS_WINPHONE @@ -827,57 +845,94 @@ void QWinRTScreen::handleExpose() HRESULT QWinRTScreen::onKeyDown(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IKeyEventArgs *args) { + Q_D(QWinRTScreen); VirtualKey virtualKey; - args->get_VirtualKey(&virtualKey); + HRESULT hr = args->get_VirtualKey(&virtualKey); + Q_ASSERT_SUCCEEDED(hr); + CorePhysicalKeyStatus status; + hr = args->get_KeyStatus(&status); + Q_ASSERT_SUCCEEDED(hr); + Qt::Key key = qKeyFromVirtual(virtualKey); // Defer character key presses to onCharacterReceived - if (key == Qt::Key_unknown || (key >= Qt::Key_Space && key <= Qt::Key_ydiaeresis)) + if (key == Qt::Key_unknown || (key >= Qt::Key_Space && key <= Qt::Key_ydiaeresis)) { + d->activeKeys.insert(key, KeyInfo(virtualKey)); return S_OK; - QWindowSystemInterface::handleKeyEvent(topWindow(), QEvent::KeyPress, key, keyboardModifiers()); + } + + QWindowSystemInterface::handleExtendedKeyEvent( + topWindow(), + QEvent::KeyPress, + key, + keyboardModifiers(), + !status.ScanCode ? -1 : status.ScanCode, + virtualKey, + 0, + QString(), + status.RepeatCount > 1, + !status.RepeatCount ? 1 : status.RepeatCount, + false); return S_OK; } HRESULT QWinRTScreen::onKeyUp(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IKeyEventArgs *args) { - Qt::KeyboardModifiers mods = keyboardModifiers(); -#ifndef Q_OS_WINPHONE Q_D(QWinRTScreen); - CorePhysicalKeyStatus status; // Look for a pressed character key - if (SUCCEEDED(args->get_KeyStatus(&status)) && d->activeKeys.contains(status.ScanCode)) { - QPair<Qt::Key, QString> keyStatus = d->activeKeys.take(status.ScanCode); - QWindowSystemInterface::handleKeyEvent(topWindow(), QEvent::KeyRelease, - keyStatus.first, mods, keyStatus.second); - return S_OK; - } -#endif // !Q_OS_WINPHONE VirtualKey virtualKey; - args->get_VirtualKey(&virtualKey); - QWindowSystemInterface::handleKeyEvent(topWindow(), QEvent::KeyRelease, - qKeyFromVirtual(virtualKey), mods); + HRESULT hr = args->get_VirtualKey(&virtualKey); + Q_ASSERT_SUCCEEDED(hr); + CorePhysicalKeyStatus status; + hr = args->get_KeyStatus(&status); + Q_ASSERT_SUCCEEDED(hr); + + Qt::Key key = qKeyFromVirtual(virtualKey); + const KeyInfo info = d->activeKeys.take(key); + QWindowSystemInterface::handleExtendedKeyEvent( + topWindow(), + QEvent::KeyRelease, + key, + keyboardModifiers(), + !status.ScanCode ? -1 : status.ScanCode, + virtualKey, + 0, + info.text, + status.RepeatCount > 1, + !status.RepeatCount ? 1 : status.RepeatCount, + false); return S_OK; } HRESULT QWinRTScreen::onCharacterReceived(ICoreWindow *, ICharacterReceivedEventArgs *args) { + Q_D(QWinRTScreen); quint32 keyCode; - args->get_KeyCode(&keyCode); + HRESULT hr = args->get_KeyCode(&keyCode); + Q_ASSERT_SUCCEEDED(hr); + CorePhysicalKeyStatus status; + hr = args->get_KeyStatus(&status); + Q_ASSERT_SUCCEEDED(hr); + // Don't generate character events for non-printables; the meta key stage is enough if (qIsNonPrintable(keyCode)) return S_OK; - Qt::KeyboardModifiers mods = keyboardModifiers(); - Qt::Key key = qKeyFromCode(keyCode, mods); - QString text = QChar(keyCode); - QWindowSystemInterface::handleKeyEvent(topWindow(), QEvent::KeyPress, key, mods, text); -#ifndef Q_OS_WINPHONE - Q_D(QWinRTScreen); - CorePhysicalKeyStatus status; // Defer release to onKeyUp for physical keys - if (SUCCEEDED(args->get_KeyStatus(&status)) && !status.IsKeyReleased) { - d->activeKeys.insert(status.ScanCode, qMakePair(key, text)); - return S_OK; - } -#endif // !Q_OS_WINPHONE - QWindowSystemInterface::handleKeyEvent(topWindow(), QEvent::KeyRelease, key, mods, text); + const Qt::KeyboardModifiers modifiers = keyboardModifiers(); + const Qt::Key key = qKeyFromCode(keyCode, modifiers); + const QString text = QChar(keyCode); + const quint32 virtualKey = d->activeKeys.value(key).virtualKey; + QWindowSystemInterface::handleExtendedKeyEvent( + topWindow(), + QEvent::KeyPress, + key, + modifiers, + !status.ScanCode ? -1 : status.ScanCode, + virtualKey, + 0, + text, + status.RepeatCount > 1, + !status.RepeatCount ? 1 : status.RepeatCount, + false); + d->activeKeys.insert(key, KeyInfo(text, virtualKey)); return S_OK; } @@ -914,6 +969,11 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args) Point point; pointerPoint->get_Position(&point); QPointF pos(point.X * d->scaleFactor, point.Y * d->scaleFactor); + QPointF localPos = pos; + if (topWindow()) { + const QPointF globalPosDelta = pos - pos.toPoint(); + localPos = topWindow()->mapFromGlobal(pos.toPoint()) + globalPosDelta; + } VirtualKeyModifiers modifiers; args->get_KeyModifiers(&modifiers); @@ -947,7 +1007,7 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args) boolean isHorizontal; properties->get_IsHorizontalMouseWheel(&isHorizontal); QPoint angleDelta(isHorizontal ? delta : 0, isHorizontal ? 0 : delta); - QWindowSystemInterface::handleWheelEvent(topWindow(), pos, pos, QPoint(), angleDelta, mods); + QWindowSystemInterface::handleWheelEvent(topWindow(), localPos, pos, QPoint(), angleDelta, mods); break; } @@ -973,7 +1033,7 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args) if (isPressed) buttons |= Qt::XButton2; - QWindowSystemInterface::handleMouseEvent(topWindow(), pos, pos, buttons, mods); + QWindowSystemInterface::handleMouseEvent(topWindow(), localPos, pos, buttons, mods); break; } diff --git a/src/plugins/platforms/winrt/qwinrttheme.cpp b/src/plugins/platforms/winrt/qwinrttheme.cpp index c32ec8a151..7d09551f5b 100644 --- a/src/plugins/platforms/winrt/qwinrttheme.cpp +++ b/src/plugins/platforms/winrt/qwinrttheme.cpp @@ -44,7 +44,13 @@ #include <wrl.h> #include <windows.ui.h> #include <windows.ui.viewmanagement.h> +#if _MSC_VER >= 1900 +#include <windows.foundation.metadata.h> +using namespace ABI::Windows::Foundation::Metadata; +#endif + using namespace Microsoft::WRL; +using namespace Microsoft::WRL::Wrappers; using namespace ABI::Windows::UI; using namespace ABI::Windows::UI::ViewManagement; @@ -73,102 +79,215 @@ static inline QColor fromColor(const Color &color) return QColor(color.R, color.G, color.B, color.A); } -QWinRTTheme::QWinRTTheme() - : d_ptr(new QWinRTThemePrivate) +#if _MSC_VER >= 1900 +static bool uiColorSettings(const wchar_t *value, UIElementType type, Color *color) { - Q_D(QWinRTTheme); + static ComPtr<IApiInformationStatics> apiInformationStatics; + HRESULT hr; + if (!apiInformationStatics) { + hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Foundation_Metadata_ApiInformation).Get(), + IID_PPV_ARGS(&apiInformationStatics)); + RETURN_FALSE_IF_FAILED("Could not get ApiInformationStatics"); + } + + static const HStringReference enumRef(L"Windows.UI.ViewManagement.UIElementType"); + HStringReference valueRef(value); + + boolean exists; + hr = apiInformationStatics->IsEnumNamedValuePresent(enumRef.Get(), valueRef.Get(), &exists); + + if (hr != S_OK || !exists) + return false; + + return SUCCEEDED(uiSettings()->UIElementColor(type, color)); +} + +static void nativeColorSettings(QPalette &p) +{ + Color color; + + if (uiColorSettings(L"ActiveCaption", UIElementType_ActiveCaption, &color)) + p.setColor(QPalette::ToolTipBase, fromColor(color)); + + if (uiColorSettings(L"Background", UIElementType_Background, &color)) + p.setColor(QPalette::AlternateBase, fromColor(color)); + + if (uiColorSettings(L"ButtonFace", UIElementType_ButtonFace, &color)) { + p.setColor(QPalette::Button, fromColor(color)); + p.setColor(QPalette::Midlight, fromColor(color).lighter(110)); + p.setColor(QPalette::Light, fromColor(color).lighter(150)); + p.setColor(QPalette::Mid, fromColor(color).dark(130)); + p.setColor(QPalette::Dark, fromColor(color).dark(150)); + } + + if (uiColorSettings(L"ButtonText", UIElementType_ButtonText, &color)) { + p.setColor(QPalette::ButtonText, fromColor(color)); + p.setColor(QPalette::Text, fromColor(color)); + } + + if (uiColorSettings(L"CaptionText", UIElementType_CaptionText, &color)) + p.setColor(QPalette::ToolTipText, fromColor(color)); + + if (uiColorSettings(L"Highlight", UIElementType_Highlight, &color)) + p.setColor(QPalette::Highlight, fromColor(color)); + + if (uiColorSettings(L"HighlightText", UIElementType_HighlightText, &color)) + p.setColor(QPalette::HighlightedText, fromColor(color)); + + if (uiColorSettings(L"Window", UIElementType_Window, &color)) { + p.setColor(QPalette::Window, fromColor(color)); + p.setColor(QPalette::Base, fromColor(color)); + } + + if (uiColorSettings(L"Hotlight", UIElementType_Hotlight, &color)) + p.setColor(QPalette::BrightText, fromColor(color)); + + //Phone related + if (uiColorSettings(L"PopupBackground", UIElementType_PopupBackground, &color)) { + p.setColor(QPalette::ToolTipBase, fromColor(color)); + p.setColor(QPalette::AlternateBase, fromColor(color)); + } + + if (uiColorSettings(L"NonTextMedium", UIElementType_NonTextMedium, &color)) + p.setColor(QPalette::Button, fromColor(color)); + + if (uiColorSettings(L"NonTextMediumHigh", UIElementType_NonTextMediumHigh, &color)) + p.setColor(QPalette::Midlight, fromColor(color)); + + if (uiColorSettings(L"NonTextHigh", UIElementType_NonTextHigh, &color)) + p.setColor(QPalette::Light, fromColor(color)); + + if (uiColorSettings(L"NonTextMediumLow", UIElementType_NonTextMediumLow, &color)) + p.setColor(QPalette::Mid, fromColor(color)); + + if (uiColorSettings(L"NonTextLow", UIElementType_NonTextLow, &color)) + p.setColor(QPalette::Dark, fromColor(color)); + + if (uiColorSettings(L"TextHigh", UIElementType_TextHigh, &color)) { + p.setColor(QPalette::ButtonText, fromColor(color)); + p.setColor(QPalette::Text, fromColor(color)); + p.setColor(QPalette::WindowText, fromColor(color)); + } + + if (uiColorSettings(L"TextMedium", UIElementType_TextMedium, &color)) + p.setColor(QPalette::ToolTipText, fromColor(color)); + + if (uiColorSettings(L"AccentColor", UIElementType_AccentColor, &color)) + p.setColor(QPalette::Highlight, fromColor(color)); + if (uiColorSettings(L"PageBackground", UIElementType_PageBackground, &color)) { + p.setColor(QPalette::Window, fromColor(color)); + p.setColor(QPalette::Base, fromColor(color)); + } + + if (uiColorSettings(L"TextContrastWithHigh", UIElementType_TextContrastWithHigh, &color)) + p.setColor(QPalette::BrightText, fromColor(color)); +} + +#else // _MSC_VER >= 1900 + +static void nativeColorSettings(QPalette &p) +{ HRESULT hr; Color color; #ifdef Q_OS_WINPHONE hr = uiSettings()->UIElementColor(UIElementType_PopupBackground, &color); Q_ASSERT_SUCCEEDED(hr); - d->palette.setColor(QPalette::ToolTipBase, fromColor(color)); - d->palette.setColor(QPalette::AlternateBase, fromColor(color)); + p.setColor(QPalette::ToolTipBase, fromColor(color)); + p.setColor(QPalette::AlternateBase, fromColor(color)); hr = uiSettings()->UIElementColor(UIElementType_NonTextMedium, &color); Q_ASSERT_SUCCEEDED(hr); - d->palette.setColor(QPalette::Button, fromColor(color)); + p.setColor(QPalette::Button, fromColor(color)); hr = uiSettings()->UIElementColor(UIElementType_NonTextMediumHigh, &color); Q_ASSERT_SUCCEEDED(hr); - d->palette.setColor(QPalette::Midlight, fromColor(color)); + p.setColor(QPalette::Midlight, fromColor(color)); hr = uiSettings()->UIElementColor(UIElementType_NonTextHigh, &color); Q_ASSERT_SUCCEEDED(hr); - d->palette.setColor(QPalette::Light, fromColor(color)); + p.setColor(QPalette::Light, fromColor(color)); hr = uiSettings()->UIElementColor(UIElementType_NonTextMediumLow, &color); Q_ASSERT_SUCCEEDED(hr); - d->palette.setColor(QPalette::Mid, fromColor(color)); + p.setColor(QPalette::Mid, fromColor(color)); hr = uiSettings()->UIElementColor(UIElementType_NonTextLow, &color); Q_ASSERT_SUCCEEDED(hr); - d->palette.setColor(QPalette::Dark, fromColor(color)); + p.setColor(QPalette::Dark, fromColor(color)); hr = uiSettings()->UIElementColor(UIElementType_TextHigh, &color); Q_ASSERT_SUCCEEDED(hr); - d->palette.setColor(QPalette::ButtonText, fromColor(color)); - d->palette.setColor(QPalette::Text, fromColor(color)); - d->palette.setColor(QPalette::WindowText, fromColor(color)); + p.setColor(QPalette::ButtonText, fromColor(color)); + p.setColor(QPalette::Text, fromColor(color)); + p.setColor(QPalette::WindowText, fromColor(color)); hr = uiSettings()->UIElementColor(UIElementType_TextMedium, &color); Q_ASSERT_SUCCEEDED(hr); - d->palette.setColor(QPalette::ToolTipText, fromColor(color)); + p.setColor(QPalette::ToolTipText, fromColor(color)); hr = uiSettings()->UIElementColor(UIElementType_AccentColor, &color); Q_ASSERT_SUCCEEDED(hr); - d->palette.setColor(QPalette::Highlight, fromColor(color)); + p.setColor(QPalette::Highlight, fromColor(color)); hr = uiSettings()->UIElementColor(UIElementType_PageBackground, &color); Q_ASSERT_SUCCEEDED(hr); - d->palette.setColor(QPalette::Window, fromColor(color)); - d->palette.setColor(QPalette::Base, fromColor(color)); + p.setColor(QPalette::Window, fromColor(color)); + p.setColor(QPalette::Base, fromColor(color)); hr = uiSettings()->UIElementColor(UIElementType_TextContrastWithHigh, &color); Q_ASSERT_SUCCEEDED(hr); - d->palette.setColor(QPalette::BrightText, fromColor(color)); + p.setColor(QPalette::BrightText, fromColor(color)); #else hr = uiSettings()->UIElementColor(UIElementType_ActiveCaption, &color); Q_ASSERT_SUCCEEDED(hr); - d->palette.setColor(QPalette::ToolTipBase, fromColor(color)); + p.setColor(QPalette::ToolTipBase, fromColor(color)); hr = uiSettings()->UIElementColor(UIElementType_Background, &color); Q_ASSERT_SUCCEEDED(hr); - d->palette.setColor(QPalette::AlternateBase, fromColor(color)); + p.setColor(QPalette::AlternateBase, fromColor(color)); hr = uiSettings()->UIElementColor(UIElementType_ButtonFace, &color); Q_ASSERT_SUCCEEDED(hr); - d->palette.setColor(QPalette::Button, fromColor(color)); - d->palette.setColor(QPalette::Midlight, fromColor(color).lighter(110)); - d->palette.setColor(QPalette::Light, fromColor(color).lighter(150)); - d->palette.setColor(QPalette::Mid, fromColor(color).dark(130)); - d->palette.setColor(QPalette::Dark, fromColor(color).dark(150)); + p.setColor(QPalette::Button, fromColor(color)); + p.setColor(QPalette::Midlight, fromColor(color).lighter(110)); + p.setColor(QPalette::Light, fromColor(color).lighter(150)); + p.setColor(QPalette::Mid, fromColor(color).dark(130)); + p.setColor(QPalette::Dark, fromColor(color).dark(150)); hr = uiSettings()->UIElementColor(UIElementType_ButtonText, &color); Q_ASSERT_SUCCEEDED(hr); - d->palette.setColor(QPalette::ButtonText, fromColor(color)); - d->palette.setColor(QPalette::Text, fromColor(color)); + p.setColor(QPalette::ButtonText, fromColor(color)); + p.setColor(QPalette::Text, fromColor(color)); hr = uiSettings()->UIElementColor(UIElementType_CaptionText, &color); Q_ASSERT_SUCCEEDED(hr); - d->palette.setColor(QPalette::ToolTipText, fromColor(color)); + p.setColor(QPalette::ToolTipText, fromColor(color)); hr = uiSettings()->UIElementColor(UIElementType_Highlight, &color); Q_ASSERT_SUCCEEDED(hr); - d->palette.setColor(QPalette::Highlight, fromColor(color)); + p.setColor(QPalette::Highlight, fromColor(color)); hr = uiSettings()->UIElementColor(UIElementType_HighlightText, &color); Q_ASSERT_SUCCEEDED(hr); - d->palette.setColor(QPalette::HighlightedText, fromColor(color)); + p.setColor(QPalette::HighlightedText, fromColor(color)); hr = uiSettings()->UIElementColor(UIElementType_Window, &color); Q_ASSERT_SUCCEEDED(hr); - d->palette.setColor(QPalette::Window, fromColor(color)); - d->palette.setColor(QPalette::Base, fromColor(color)); + p.setColor(QPalette::Window, fromColor(color)); + p.setColor(QPalette::Base, fromColor(color)); hr = uiSettings()->UIElementColor(UIElementType_Hotlight, &color); Q_ASSERT_SUCCEEDED(hr); - d->palette.setColor(QPalette::BrightText, fromColor(color)); + p.setColor(QPalette::BrightText, fromColor(color)); #endif } +#endif // _MSC_VER < 1900 + +QWinRTTheme::QWinRTTheme() + : d_ptr(new QWinRTThemePrivate) +{ + Q_D(QWinRTTheme); + + nativeColorSettings(d->palette); +} bool QWinRTTheme::usePlatformNativeDialog(DialogType type) const { diff --git a/src/plugins/platforms/winrt/qwinrtwindow.cpp b/src/plugins/platforms/winrt/qwinrtwindow.cpp index c5b06a5d8a..0d43e76c1a 100644 --- a/src/plugins/platforms/winrt/qwinrtwindow.cpp +++ b/src/plugins/platforms/winrt/qwinrtwindow.cpp @@ -175,6 +175,9 @@ QWinRTWindow::~QWinRTWindow() }); RETURN_VOID_IF_FAILED("Failed to completely destroy window resources, likely because the application is shutting down"); + if (!d->surface) + return; + EGLBoolean value = eglDestroySurface(d->display, d->surface); d->surface = EGL_NO_SURFACE; if (value == EGL_FALSE) diff --git a/src/plugins/platforms/winrt/winrt.pro b/src/plugins/platforms/winrt/winrt.pro index 2718ea62bb..be6aad02d1 100644 --- a/src/plugins/platforms/winrt/winrt.pro +++ b/src/plugins/platforms/winrt/winrt.pro @@ -10,7 +10,7 @@ QT += core-private gui-private platformsupport-private DEFINES *= QT_NO_CAST_FROM_ASCII __WRL_NO_DEFAULT_LIB__ GL_GLEXT_PROTOTYPES -LIBS += $$QMAKE_LIBS_CORE -ldwrite +LIBS += $$QMAKE_LIBS_CORE -ldwrite -ld3d11 INCLUDEPATH += $$QT_SOURCE_TREE/src/3rdparty/freetype/include SOURCES = \ diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp index e62d515b62..1825a463d0 100644 --- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp +++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp @@ -146,8 +146,8 @@ QXcbShmImage::QXcbShmImage(QXcbScreen *screen, const QSize &size, uint depth, QI int id = shmget(IPC_PRIVATE, segmentSize, IPC_CREAT | 0600); if (id == -1) - qWarning("QXcbShmImage: shmget() failed (%d) for size %d (%dx%d)", - errno, segmentSize, size.width(), size.height()); + qWarning("QXcbShmImage: shmget() failed (%d: %s) for size %d (%dx%d)", + errno, strerror(errno), segmentSize, size.width(), size.height()); else m_shm_info.shmid = id; m_shm_info.shmaddr = m_xcb_image->data = (quint8 *)shmat (m_shm_info.shmid, 0, 0); @@ -311,9 +311,12 @@ QPaintDevice *QXcbBackingStore::paintDevice() void QXcbBackingStore::beginPaint(const QRegion ®ion) { + if (!m_image && !m_size.isEmpty()) + resize(m_size, QRegion()); + if (!m_image) return; - + m_size = QSize(); m_paintRegion = region; m_image->preparePaint(m_paintRegion); @@ -420,7 +423,8 @@ void QXcbBackingStore::resize(const QSize &size, const QRegion &) return; Q_XCB_NOOP(connection()); - QXcbScreen *screen = static_cast<QXcbScreen *>(window()->screen()->handle()); + + QXcbScreen *screen = window()->screen() ? static_cast<QXcbScreen *>(window()->screen()->handle()) : 0; QPlatformWindow *pw = window()->handle(); if (!pw) { window()->create(); @@ -429,6 +433,11 @@ void QXcbBackingStore::resize(const QSize &size, const QRegion &) QXcbWindow* win = static_cast<QXcbWindow *>(pw); delete m_image; + if (!screen) { + m_image = 0; + m_size = size; + return; + } m_image = new QXcbShmImage(screen, size, win->depth(), win->imageFormat()); // Slow path for bgr888 VNC: Create an additional image, paint into that and // swap R and B while copying to m_image after each paint. diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.h b/src/plugins/platforms/xcb/qxcbbackingstore.h index b58a32d313..1bea36d423 100644 --- a/src/plugins/platforms/xcb/qxcbbackingstore.h +++ b/src/plugins/platforms/xcb/qxcbbackingstore.h @@ -71,6 +71,7 @@ private: QXcbShmImage *m_image; QRegion m_paintRegion; QImage m_rgbImage; + QSize m_size; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index bde8826792..b691c7550f 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -652,7 +652,7 @@ void QXcbWindow::setGeometry(const QRect &rect) m_xcbScreen = newScreen; const QRect wmGeometry = windowToWmGeometry(rect); - if (newScreen != currentScreen) + if (newScreen && newScreen != currentScreen) QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->QPlatformScreen::screen()); if (qt_window_private(window())->positionAutomatic) { @@ -1606,7 +1606,7 @@ void QXcbWindow::requestActivateWindow() return; } - if (!m_mapped) { + if (!m_mapped || !xcbScreen()) { m_deferredActivation = true; return; } diff --git a/src/plugins/styles/bb10style/qpixmapstyle.cpp b/src/plugins/styles/bb10style/qpixmapstyle.cpp index 759f57eb1c..3090c42959 100644 --- a/src/plugins/styles/bb10style/qpixmapstyle.cpp +++ b/src/plugins/styles/bb10style/qpixmapstyle.cpp @@ -616,9 +616,9 @@ void QPixmapStyle::drawProgressBarBackground(const QStyleOption *option, QPainter *painter, const QWidget *) const { bool vertical = false; - if (const QStyleOptionProgressBarV2 *pb2 = - qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option)) { - vertical = (pb2->orientation == Qt::Vertical); + if (const QStyleOptionProgressBar *pb = + qstyleoption_cast<const QStyleOptionProgressBar *>(option)) { + vertical = pb->orientation == Qt::Vertical; } drawCachedPixmap(vertical ? PB_VBackground : PB_HBackground, option->rect, painter); } @@ -628,11 +628,7 @@ void QPixmapStyle::drawProgressBarLabel(const QStyleOption *option, { if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) { - bool vertical = false; - if (const QStyleOptionProgressBarV2 *pb2 = - qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option)) { - vertical = (pb2->orientation == Qt::Vertical); - } + const bool vertical = pb->orientation == Qt::Vertical; if (!vertical) { QPalette::ColorRole textRole = QPalette::ButtonText; proxy()->drawItemText(painter, pb->rect, @@ -647,13 +643,8 @@ void QPixmapStyle::drawProgressBarFill(const QStyleOption *option, { const QStyleOptionProgressBar *pbar = qstyleoption_cast<const QStyleOptionProgressBar*>(option); - bool vertical = false; - bool flip = pbar->direction == Qt::RightToLeft; - if (const QStyleOptionProgressBarV2 *pb2 = - qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option)) { - vertical = (pb2->orientation == Qt::Vertical); - flip = flip ^ pb2->invertedAppearance; - } + const bool vertical = pbar->orientation == Qt::Vertical; + const bool flip = (pbar->direction == Qt::RightToLeft) ^ pbar->invertedAppearance; if (pbar->progress == pbar->maximum) { drawCachedPixmap(vertical ? PB_VComplete : PB_HComplete, option->rect, painter); @@ -801,9 +792,9 @@ QSize QPixmapStyle::progressBarSizeFromContents(const QStyleOption *option, const QWidget *widget) const { bool vertical = false; - if (const QStyleOptionProgressBarV2 *pb2 = - qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option)) { - vertical = (pb2->orientation == Qt::Vertical); + if (const QStyleOptionProgressBar *pb = + qstyleoption_cast<const QStyleOptionProgressBar *>(option)) { + vertical = pb->orientation == Qt::Vertical; } QSize result = QCommonStyle::sizeFromContents(CT_Slider, option, contentsSize, widget); if (vertical) { |