summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms')
-rw-r--r--src/plugins/platforms/android/androidjniaccessibility.cpp62
-rw-r--r--src/plugins/platforms/android/androidjnimain.cpp7
-rw-r--r--src/plugins/platforms/android/qandroidinputcontext.cpp20
-rw-r--r--src/plugins/platforms/android/qandroidplatformintegration.cpp14
-rw-r--r--src/plugins/platforms/android/qandroidplatformintegration.h1
-rw-r--r--src/plugins/platforms/android/qandroidplatformopenglcontext.cpp5
-rw-r--r--src/plugins/platforms/android/qandroidplatformopenglwindow.cpp33
-rw-r--r--src/plugins/platforms/android/qandroidplatformopenglwindow.h2
-rw-r--r--src/plugins/platforms/android/qandroidplatformrasterwindow.cpp2
-rw-r--r--src/plugins/platforms/android/qandroidplatformscreen.cpp15
-rw-r--r--src/plugins/platforms/android/qandroidplatformwindow.cpp4
-rw-r--r--src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm2
-rw-r--r--src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm2
-rw-r--r--src/plugins/platforms/cocoa/qcocoaeventdispatcher.h4
-rw-r--r--src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm91
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.h3
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.mm17
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuloader.mm2
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm31
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.cpp1
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp276
-rw-r--r--src/plugins/platforms/ios/quiview_textinput.mm6
-rw-r--r--src/plugins/platforms/qnx/qqnxnativeinterface.cpp8
-rw-r--r--src/plugins/platforms/qnx/qqnxnativeinterface.h3
-rw-r--r--src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp6
-rw-r--r--src/plugins/platforms/windows/qwindowsfontdatabase.cpp36
-rw-r--r--src/plugins/platforms/windows/qwindowsmousehandler.cpp1
-rw-r--r--src/plugins/platforms/windows/qwindowstabletsupport.cpp4
-rw-r--r--src/plugins/platforms/winrt/qwinrtbackingstore.cpp22
-rw-r--r--src/plugins/platforms/winrt/qwinrtbackingstore.h3
-rw-r--r--src/plugins/platforms/winrt/qwinrtcursor.cpp2
-rw-r--r--src/plugins/platforms/winrt/qwinrtfontdatabase.cpp17
-rw-r--r--src/plugins/platforms/winrt/qwinrtfontdatabase.h8
-rw-r--r--src/plugins/platforms/winrt/qwinrtinputcontext.cpp53
-rw-r--r--src/plugins/platforms/winrt/qwinrtplatformmessagedialoghelper.cpp7
-rw-r--r--src/plugins/platforms/winrt/qwinrtplatformtheme.cpp12
-rw-r--r--src/plugins/platforms/winrt/qwinrtscreen.cpp157
-rw-r--r--src/plugins/platforms/winrt/qwinrtscreen.h22
-rw-r--r--src/plugins/platforms/winrt/qwinrtservices.cpp15
-rw-r--r--src/plugins/platforms/winrt/qwinrtwindow.cpp5
-rw-r--r--src/plugins/platforms/winrt/qwinrtwindow.h2
-rw-r--r--src/plugins/platforms/winrt/winrt.pro8
-rw-r--r--src/plugins/platforms/xcb/qglxintegration.cpp9
-rw-r--r--src/plugins/platforms/xcb/qxcbbackingstore.cpp16
-rw-r--r--src/plugins/platforms/xcb/qxcbbackingstore.h1
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp5
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.h3
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.cpp1
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp25
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.h15
50 files changed, 732 insertions, 334 deletions
diff --git a/src/plugins/platforms/android/androidjniaccessibility.cpp b/src/plugins/platforms/android/androidjniaccessibility.cpp
index fa7e259460..d9f5cec27a 100644
--- a/src/plugins/platforms/android/androidjniaccessibility.cpp
+++ b/src/plugins/platforms/android/androidjniaccessibility.cpp
@@ -56,6 +56,18 @@ static const char m_methodErrorMsg[] = "Can't find method \"%s%s\"";
namespace QtAndroidAccessibility
{
+ static jmethodID m_addActionMethodID = 0;
+ static jmethodID m_setCheckableMethodID = 0;
+ static jmethodID m_setCheckedMethodID = 0;
+ static jmethodID m_setClickableMethodID = 0;
+ static jmethodID m_setContentDescriptionMethodID = 0;
+ static jmethodID m_setEnabledMethodID = 0;
+ static jmethodID m_setFocusableMethodID = 0;
+ static jmethodID m_setFocusedMethodID = 0;
+ static jmethodID m_setTextSelectionMethodID = 0;
+ static jmethodID m_setVisibleToUserMethodID = 0;
+
+
static void setActive(JNIEnv */*env*/, jobject /*thiz*/, jboolean active)
{
QAndroidPlatformIntegration *platformIntegration = QtAndroid::androidPlatformIntegration();
@@ -164,17 +176,6 @@ if (!clazz) { \
//__android_log_print(ANDROID_LOG_FATAL, m_qtTag, m_methodErrorMsg, METHOD_NAME, METHOD_SIGNATURE);
-#define CALL_METHOD(OBJECT, METHOD_NAME, METHOD_SIGNATURE, ...) \
-{ \
- jclass clazz = env->GetObjectClass(OBJECT); \
- jmethodID method = env->GetMethodID(clazz, METHOD_NAME, METHOD_SIGNATURE); \
- if (!method) { \
- __android_log_print(ANDROID_LOG_WARN, m_qtTag, m_methodErrorMsg, METHOD_NAME, METHOD_SIGNATURE); \
- return false; \
- } \
- env->CallVoidMethod(OBJECT, method, __VA_ARGS__); \
-}
-
static jstring descriptionForAccessibleObject(JNIEnv *env, jobject /*thiz*/, jint objectId)
{
@@ -210,30 +211,30 @@ if (!clazz) { \
int startSelection;
int endSelection;
textIface->selection(0, &startSelection, &endSelection);
- CALL_METHOD(node, "setTextSelection", "(II)V", startSelection, endSelection)
+ env->CallVoidMethod(node, m_setTextSelectionMethodID, startSelection, endSelection);
}
}
- CALL_METHOD(node, "setEnabled", "(Z)V", !state.disabled)
- CALL_METHOD(node, "setFocusable", "(Z)V", (bool)state.focusable)
- CALL_METHOD(node, "setFocused", "(Z)V", (bool)state.focused)
- CALL_METHOD(node, "setCheckable", "(Z)V", (bool)state.checkable)
- CALL_METHOD(node, "setChecked", "(Z)V", (bool)state.checked)
- CALL_METHOD(node, "setVisibleToUser", "(Z)V", !state.invisible)
+ env->CallVoidMethod(node, m_setEnabledMethodID, !state.disabled);
+ env->CallVoidMethod(node, m_setCheckedMethodID, (bool)state.checked);
+ env->CallVoidMethod(node, m_setFocusableMethodID, (bool)state.focusable);
+ env->CallVoidMethod(node, m_setFocusedMethodID, (bool)state.focused);
+ env->CallVoidMethod(node, m_setCheckableMethodID, (bool)state.checkable);
+ env->CallVoidMethod(node, m_setVisibleToUserMethodID, !state.invisible);
if (iface->actionInterface()) {
QStringList actions = iface->actionInterface()->actionNames();
bool clickable = actions.contains(QAccessibleActionInterface::pressAction());
bool toggle = actions.contains(QAccessibleActionInterface::toggleAction());
if (clickable || toggle) {
- CALL_METHOD(node, "setClickable", "(Z)V", (bool)clickable)
- CALL_METHOD(node, "addAction", "(I)V", 16) // ACTION_CLICK defined in AccessibilityNodeInfo
+ env->CallVoidMethod(node, m_setClickableMethodID, (bool)clickable);
+ env->CallVoidMethod(node, m_addActionMethodID, (int)16); // ACTION_CLICK defined in AccessibilityNodeInfo
}
}
jstring jdesc = env->NewString((jchar*) desc.constData(), (jsize) desc.size());
//CALL_METHOD(node, "setText", "(Ljava/lang/CharSequence;)V", jdesc)
- CALL_METHOD(node, "setContentDescription", "(Ljava/lang/CharSequence;)V", jdesc)
+ env->CallVoidMethod(node, m_setContentDescriptionMethodID, jdesc);
return true;
}
@@ -249,6 +250,13 @@ if (!clazz) { \
{"clickAction", "(I)Z", (void*)clickAction},
};
+#define GET_AND_CHECK_STATIC_METHOD(VAR, CLASS, METHOD_NAME, METHOD_SIGNATURE) \
+ VAR = env->GetMethodID(CLASS, METHOD_NAME, METHOD_SIGNATURE); \
+ if (!VAR) { \
+ __android_log_print(ANDROID_LOG_FATAL, QtAndroid::qtTagText(), QtAndroid::methodErrorMsgFmt(), METHOD_NAME, METHOD_SIGNATURE); \
+ return false; \
+ }
+
bool registerNatives(JNIEnv *env)
{
jclass clazz;
@@ -260,6 +268,18 @@ if (!clazz) { \
return false;
}
+ jclass nodeInfoClass = env->FindClass("android/view/accessibility/AccessibilityNodeInfo");
+ GET_AND_CHECK_STATIC_METHOD(m_addActionMethodID, nodeInfoClass, "addAction", "(I)V");
+ GET_AND_CHECK_STATIC_METHOD(m_setCheckableMethodID, nodeInfoClass, "setCheckable", "(Z)V");
+ GET_AND_CHECK_STATIC_METHOD(m_setCheckedMethodID, nodeInfoClass, "setChecked", "(Z)V");
+ GET_AND_CHECK_STATIC_METHOD(m_setClickableMethodID, nodeInfoClass, "setClickable", "(Z)V");
+ GET_AND_CHECK_STATIC_METHOD(m_setContentDescriptionMethodID, nodeInfoClass, "setContentDescription", "(Ljava/lang/CharSequence;)V");
+ GET_AND_CHECK_STATIC_METHOD(m_setEnabledMethodID, nodeInfoClass, "setEnabled", "(Z)V");
+ GET_AND_CHECK_STATIC_METHOD(m_setFocusableMethodID, nodeInfoClass, "setFocusable", "(Z)V");
+ GET_AND_CHECK_STATIC_METHOD(m_setFocusedMethodID, nodeInfoClass, "setFocused", "(Z)V");
+ GET_AND_CHECK_STATIC_METHOD(m_setTextSelectionMethodID, nodeInfoClass, "setTextSelection", "(II)V");
+ GET_AND_CHECK_STATIC_METHOD(m_setVisibleToUserMethodID, nodeInfoClass, "setVisibleToUser", "(Z)V");
+
return true;
}
}
diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp
index 7ca4db710b..d484a2faff 100644
--- a/src/plugins/platforms/android/androidjnimain.cpp
+++ b/src/plugins/platforms/android/androidjnimain.cpp
@@ -573,8 +573,11 @@ static void updateWindow(JNIEnv */*env*/, jobject /*thiz*/)
return;
if (QGuiApplication::instance() != 0) {
- foreach (QWindow *w, QGuiApplication::topLevelWindows())
- QWindowSystemInterface::handleExposeEvent(w, QRegion(w->geometry()));
+ foreach (QWindow *w, QGuiApplication::topLevelWindows()) {
+ QRect availableGeometry = w->screen()->availableGeometry();
+ if (w->geometry().width() > 0 && w->geometry().height() > 0 && availableGeometry.width() > 0 && availableGeometry.height() > 0)
+ QWindowSystemInterface::handleExposeEvent(w, QRegion(w->geometry()));
+ }
}
QAndroidPlatformScreen *screen = static_cast<QAndroidPlatformScreen *>(m_androidPlatformIntegration->screen());
diff --git a/src/plugins/platforms/android/qandroidinputcontext.cpp b/src/plugins/platforms/android/qandroidinputcontext.cpp
index c2e5f83639..5d47d2fda4 100644
--- a/src/plugins/platforms/android/qandroidinputcontext.cpp
+++ b/src/plugins/platforms/android/qandroidinputcontext.cpp
@@ -472,12 +472,24 @@ void QAndroidInputContext::updateCursorPosition()
if (m_composingText.isEmpty() != (m_composingTextStart == -1))
qWarning() << "Input method out of sync" << m_composingText << m_composingTextStart;
-
- // Qt's idea of the cursor position is the start of the preedit area, so we have to maintain our own preedit cursor pos
int realCursorPosition = cursorPos;
+ int realAnchorPosition = cursorPos;
+
+ int cpos = query->value(Qt::ImCursorPosition).toInt();
+ int anchor = query->value(Qt::ImAnchorPosition).toInt();
+ if (cpos != anchor) {
+ if (!m_composingText.isEmpty()) {
+ qWarning("Selecting text while preediting may give unpredictable results.");
+ finishComposingText();
+ }
+ int blockPos = getBlockPosition(query);
+ realCursorPosition = blockPos + cpos;
+ realAnchorPosition = blockPos + anchor;
+ }
+ // Qt's idea of the cursor position is the start of the preedit area, so we maintain our own preedit cursor pos
if (!m_composingText.isEmpty())
- realCursorPosition = m_composingCursor;
- QtAndroidInput::updateSelection(realCursorPosition, realCursorPosition, //empty selection
+ realCursorPosition = realAnchorPosition = m_composingCursor;
+ QtAndroidInput::updateSelection(realCursorPosition, realAnchorPosition,
m_composingTextStart, m_composingTextStart + composeLength); // pre-edit text
}
}
diff --git a/src/plugins/platforms/android/qandroidplatformintegration.cpp b/src/plugins/platforms/android/qandroidplatformintegration.cpp
index 7f0f40be0f..213b1bb7e6 100644
--- a/src/plugins/platforms/android/qandroidplatformintegration.cpp
+++ b/src/plugins/platforms/android/qandroidplatformintegration.cpp
@@ -45,11 +45,14 @@
#include <QGuiApplication>
#include <QOpenGLContext>
#include <QThread>
+#include <QOffscreenSurface>
#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
+#include <QtPlatformSupport/private/qeglpbuffer_p.h>
#include <qpa/qwindowsysteminterface.h>
#include <qpa/qplatformwindow.h>
+#include <qpa/qplatformoffscreensurface.h>
#include "androidjnimain.h"
#include "qabstracteventdispatcher.h"
@@ -207,6 +210,17 @@ QPlatformOpenGLContext *QAndroidPlatformIntegration::createPlatformOpenGLContext
return new QAndroidPlatformOpenGLContext(format, context->shareHandle(), m_eglDisplay);
}
+QPlatformOffscreenSurface *QAndroidPlatformIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const
+{
+ QSurfaceFormat format(surface->requestedFormat());
+ format.setAlphaBufferSize(8);
+ format.setRedBufferSize(8);
+ format.setGreenBufferSize(8);
+ format.setBlueBufferSize(8);
+
+ return new QEGLPbuffer(m_eglDisplay, format, surface);
+}
+
QPlatformWindow *QAndroidPlatformIntegration::createPlatformWindow(QWindow *window) const
{
if (window->type() == Qt::ForeignWindow)
diff --git a/src/plugins/platforms/android/qandroidplatformintegration.h b/src/plugins/platforms/android/qandroidplatformintegration.h
index 4a3fe6c766..f8fa1a91dd 100644
--- a/src/plugins/platforms/android/qandroidplatformintegration.h
+++ b/src/plugins/platforms/android/qandroidplatformintegration.h
@@ -82,6 +82,7 @@ public:
QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const;
QAbstractEventDispatcher *createEventDispatcher() const;
QAndroidPlatformScreen *screen() { return m_primaryScreen; }
+ QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const;
virtual void setDesktopSize(int width, int height);
virtual void setDisplayMetrics(int width, int height);
diff --git a/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp b/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp
index 152a06c99d..53047585cf 100644
--- a/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp
+++ b/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp
@@ -44,6 +44,8 @@
#include "qandroidplatformopenglwindow.h"
#include "qandroidplatformintegration.h"
+#include <QtPlatformSupport/private/qeglpbuffer_p.h>
+
#include <QSurface>
#include <QtGui/private/qopenglcontext_p.h>
@@ -98,7 +100,8 @@ EGLSurface QAndroidPlatformOpenGLContext::eglSurfaceForPlatformSurface(QPlatform
{
if (surface->surface()->surfaceClass() == QSurface::Window)
return static_cast<QAndroidPlatformOpenGLWindow *>(surface)->eglSurface(eglConfig());
- return EGL_NO_SURFACE;
+ else
+ return static_cast<QEGLPbuffer *>(surface)->pbuffer();
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/qandroidplatformopenglwindow.cpp b/src/plugins/platforms/android/qandroidplatformopenglwindow.cpp
index 34db729289..f0c4a1de2a 100644
--- a/src/plugins/platforms/android/qandroidplatformopenglwindow.cpp
+++ b/src/plugins/platforms/android/qandroidplatformopenglwindow.cpp
@@ -47,7 +47,8 @@
#include <QSurfaceFormat>
#include <qpa/qwindowsysteminterface.h>
-
+#include <qpa/qplatformscreen.h>
+#include <QtPlatformSupport/private/qeglconvenience_p.h>
#include <android/native_window.h>
#include <android/native_window_jni.h>
@@ -77,8 +78,20 @@ void QAndroidPlatformOpenGLWindow::setGeometry(const QRect &rect)
if (rect == geometry())
return;
+ QRect oldGeometry = geometry();
+
QAndroidPlatformWindow::setGeometry(rect);
QtAndroid::setSurfaceGeometry(m_nativeSurfaceId, rect);
+
+ QRect availableGeometry = screen()->availableGeometry();
+ if (oldGeometry.width() == 0
+ && oldGeometry.height() == 0
+ && rect.width() > 0
+ && rect.height() > 0
+ && availableGeometry.width() > 0
+ && availableGeometry.height() > 0) {
+ QWindowSystemInterface::handleExposeEvent(window(), QRegion(rect));
+ }
}
EGLSurface QAndroidPlatformOpenGLWindow::eglSurface(EGLConfig config)
@@ -100,8 +113,11 @@ void QAndroidPlatformOpenGLWindow::checkNativeSurface(EGLConfig config)
createEgl(config);
+
// we've create another surface, the window should be repainted
- QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry()));
+ QRect availableGeometry = screen()->availableGeometry();
+ if (geometry().width() > 0 && geometry().height() > 0 && availableGeometry.width() > 0 && availableGeometry.height() > 0)
+ QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry()));
}
void QAndroidPlatformOpenGLWindow::createEgl(EGLConfig config)
@@ -111,6 +127,7 @@ void QAndroidPlatformOpenGLWindow::createEgl(EGLConfig config)
m_nativeWindow = ANativeWindow_fromSurface(env, m_androidSurfaceObject.object());
m_androidSurfaceObject = QJNIObjectPrivate();
m_eglSurface = eglCreateWindowSurface(m_eglDisplay, config, m_nativeWindow, NULL);
+ m_format = q_glFormatFromConfig(m_eglDisplay, config, window()->requestedFormat());
if (m_eglSurface == EGL_NO_SURFACE) {
EGLint error = eglGetError();
eglTerminate(m_eglDisplay);
@@ -118,6 +135,14 @@ void QAndroidPlatformOpenGLWindow::createEgl(EGLConfig config)
}
}
+QSurfaceFormat QAndroidPlatformOpenGLWindow::format() const
+{
+ if (m_nativeWindow == 0)
+ return window()->requestedFormat();
+ else
+ return m_format;
+}
+
void QAndroidPlatformOpenGLWindow::clearEgl()
{
eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
@@ -143,7 +168,9 @@ void QAndroidPlatformOpenGLWindow::surfaceChanged(JNIEnv *jniEnv, jobject surfac
unlockSurface();
// repaint the window
- QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry()));
+ QRect availableGeometry = screen()->availableGeometry();
+ if (geometry().width() > 0 && geometry().height() > 0 && availableGeometry.width() > 0 && availableGeometry.height() > 0)
+ QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry()));
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/qandroidplatformopenglwindow.h b/src/plugins/platforms/android/qandroidplatformopenglwindow.h
index 7af8b722aa..83df15a524 100644
--- a/src/plugins/platforms/android/qandroidplatformopenglwindow.h
+++ b/src/plugins/platforms/android/qandroidplatformopenglwindow.h
@@ -60,6 +60,7 @@ public:
void setGeometry(const QRect &rect);
EGLSurface eglSurface(EGLConfig config);
+ QSurfaceFormat format() const;
void checkNativeSurface(EGLConfig config);
@@ -76,6 +77,7 @@ private:
int m_nativeSurfaceId = -1;
QJNIObjectPrivate m_androidSurfaceObject;
QWaitCondition m_surfaceWaitCondition;
+ QSurfaceFormat m_format;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/qandroidplatformrasterwindow.cpp b/src/plugins/platforms/android/qandroidplatformrasterwindow.cpp
index eb5a73c4a3..3fb236793b 100644
--- a/src/plugins/platforms/android/qandroidplatformrasterwindow.cpp
+++ b/src/plugins/platforms/android/qandroidplatformrasterwindow.cpp
@@ -76,6 +76,8 @@ void QAndroidPlatformRasterWindow::setGeometry(const QRect &rect)
{
m_oldGeometry = geometry();
QAndroidPlatformWindow::setGeometry(rect);
+ if (rect.topLeft() != m_oldGeometry.topLeft())
+ repaint(QRegion(rect));
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/qandroidplatformscreen.cpp b/src/plugins/platforms/android/qandroidplatformscreen.cpp
index f03f551d8a..e67a039ff4 100644
--- a/src/plugins/platforms/android/qandroidplatformscreen.cpp
+++ b/src/plugins/platforms/android/qandroidplatformscreen.cpp
@@ -55,6 +55,9 @@
#include <android/bitmap.h>
#include <android/native_window_jni.h>
+#include <QtGui/QGuiApplication>
+#include <QtGui/QWindow>
+
QT_BEGIN_NAMESPACE
#ifdef QANDROIDPLATFORMSCREEN_DEBUG
@@ -217,11 +220,23 @@ void QAndroidPlatformScreen::setGeometry(const QRect &rect)
if (m_geometry == rect)
return;
+ QRect oldGeometry = m_geometry;
+
m_geometry = rect;
QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), geometry());
QWindowSystemInterface::handleScreenAvailableGeometryChange(QPlatformScreen::screen(), availableGeometry());
resizeMaximizedWindows();
+ if (oldGeometry.width() == 0 && oldGeometry.height() == 0 && rect.width() > 0 && rect.height() > 0) {
+ QList<QWindow *> windows = QGuiApplication::allWindows();
+ for (int i = 0; i < windows.size(); ++i) {
+ QWindow *w = windows.at(i);
+ QRect geometry = w->handle()->geometry();
+ if (geometry.width() > 0 && geometry.height() > 0)
+ QWindowSystemInterface::handleExposeEvent(w, QRegion(geometry));
+ }
+ }
+
if (m_id != -1) {
if (m_nativeSurface) {
ANativeWindow_release(m_nativeSurface);
diff --git a/src/plugins/platforms/android/qandroidplatformwindow.cpp b/src/plugins/platforms/android/qandroidplatformwindow.cpp
index b4231f0283..558525b78c 100644
--- a/src/plugins/platforms/android/qandroidplatformwindow.cpp
+++ b/src/plugins/platforms/android/qandroidplatformwindow.cpp
@@ -88,7 +88,9 @@ void QAndroidPlatformWindow::setVisible(bool visible)
setGeometry(platformScreen()->availableGeometry());
}
- QPlatformWindow::setVisible(visible);
+ QRect availableGeometry = screen()->availableGeometry();
+ if (geometry().width() > 0 && geometry().height() > 0 && availableGeometry.width() > 0 && availableGeometry.height() > 0)
+ QPlatformWindow::setVisible(visible);
if (visible)
platformScreen()->addWindow(this);
diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
index 6d2c2a401e..b309df6242 100644
--- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
+++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
@@ -380,7 +380,7 @@
- (BOOL)accessibilityIsAttributeSettable:(NSString *)attribute {
QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
if (!iface)
- return nil;
+ return NO;
if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) {
return iface->state().focusable ? YES : NO;
diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
index d322079cb2..a2f9f8c984 100644
--- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
+++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
@@ -124,7 +124,7 @@ static void cleanupCocoaApplicationDelegate()
[dockMenu release];
[qtMenuLoader release];
if (reflectionDelegate) {
- [NSApp setDelegate:reflectionDelegate];
+ [[NSApplication sharedApplication] setDelegate:reflectionDelegate];
[reflectionDelegate release];
}
[[NSNotificationCenter defaultCenter] removeObserver:self];
diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h
index de6c6585e9..dc0b8fcc18 100644
--- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h
+++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h
@@ -134,8 +134,6 @@ public:
void interrupt();
void flush();
- bool event(QEvent *);
-
friend void qt_mac_maybeCancelWaitForMoreEventsForwarder(QAbstractEventDispatcher *eventDispatcher);
};
@@ -180,6 +178,8 @@ public:
void maybeCancelWaitForMoreEvents();
void ensureNSAppInitialized();
+ void removeQueuedUserInputEvents(int nsWinNumber);
+
QCFSocketNotifier cfSocketNotifier;
QList<void *> queuedUserInputEvents; // NSEvent *
CFRunLoopSourceRef postedEventsSource;
diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
index e0ce9f9648..e7f8992c6d 100644
--- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
+++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
@@ -415,6 +415,11 @@ bool QCocoaEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)
// 'session' as well. As a result, we need to restart all internal sessions:
d->temporarilyStopAllModalSessions();
}
+
+ // Clean up the modal session list, call endModalSession.
+ if (d->cleanupModalSessionsNeeded)
+ d->cleanupModalSessions();
+
} else {
d->nsAppRunCalledByQt = true;
QBoolBlocker execGuard(d->currentExecIsNSAppRun, true);
@@ -441,6 +446,11 @@ bool QCocoaEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)
// 'session' as well. As a result, we need to restart all internal sessions:
d->temporarilyStopAllModalSessions();
}
+
+ // Clean up the modal session list, call endModalSession.
+ if (d->cleanupModalSessionsNeeded)
+ d->cleanupModalSessions();
+
retVal = true;
} else do {
// Dispatch all non-user events (but que non-user events up for later). In
@@ -622,7 +632,8 @@ NSModalSession QCocoaEventDispatcherPrivate::currentModalSession()
if (!info.session) {
QCocoaAutoReleasePool pool;
- NSWindow *nswindow = static_cast<QCocoaWindow *>(info.window->handle())->nativeWindow();
+ QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(info.window->handle());
+ NSWindow *nswindow = cocoaWindow->nativeWindow();
if (!nswindow)
continue;
@@ -630,7 +641,10 @@ NSModalSession QCocoaEventDispatcherPrivate::currentModalSession()
QBoolBlocker block1(blockSendPostedEvents, true);
info.nswindow = nswindow;
[(NSWindow*) info.nswindow retain];
+ QRect rect = cocoaWindow->geometry();
info.session = [NSApp beginModalSessionForWindow:nswindow];
+ if (rect != cocoaWindow->geometry())
+ cocoaWindow->setGeometry(rect);
}
currentModalSessionCached = info.session;
cleanupModalSessionsNeeded = false;
@@ -717,10 +731,9 @@ void QCocoaEventDispatcherPrivate::beginModalSession(QWindow *window)
{
// We need to start spinning the modal session. Usually this is done with
// QDialog::exec() for Qt Widgets based applications, but for others that
- // just call show(), we need to interrupt(). We call this here, before
- // setting currentModalSessionCached to zero, so that interrupt() calls
- // [NSApp abortModal] if another modal session is currently running
+ // just call show(), we need to interrupt().
Q_Q(QCocoaEventDispatcher);
+ q->interrupt();
// Add a new, empty (null), NSModalSession to the stack.
// It will become active the next time QEventDispatcher::processEvents is called.
@@ -733,24 +746,6 @@ void QCocoaEventDispatcherPrivate::beginModalSession(QWindow *window)
cocoaModalSessionStack.push(info);
updateChildrenWorksWhenModal();
currentModalSessionCached = 0;
- if (currentExecIsNSAppRun) {
- QEvent *e = new QEvent(QEvent::User);
- qApp->postEvent(q, e, Qt::HighEventPriority);
- } else {
- q->interrupt();
- }
-}
-
-bool QCocoaEventDispatcher::event(QEvent *e)
-{
- Q_D(QCocoaEventDispatcher);
-
- if (e->type() == QEvent::User) {
- d->q_func()->processEvents(QEventLoop::DialogExec | QEventLoop::EventLoopExec | QEventLoop::WaitForMoreEvents);
- return true;
- }
-
- return QObject::event(e);
}
void QCocoaEventDispatcherPrivate::endModalSession(QWindow *window)
@@ -772,10 +767,7 @@ void QCocoaEventDispatcherPrivate::endModalSession(QWindow *window)
info.window = 0;
if (i + endedSessions == stackSize-1) {
// The top sessions ended. Interrupt the event dispatcher to
- // start spinning the correct session immediately. Like in
- // beginModalSession(), we call interrupt() before clearing
- // currentModalSessionCached to make sure we stop any currently
- // running modal session with [NSApp abortModal]
+ // start spinning the correct session immediately.
q->interrupt();
currentModalSessionCached = 0;
cleanupModalSessionsNeeded = true;
@@ -878,10 +870,7 @@ void QCocoaEventDispatcherPrivate::processPostedEvents()
return;
}
- if (cleanupModalSessionsNeeded)
- cleanupModalSessions();
-
- if (interrupt) {
+ if (processEventsCalled > 0 && interrupt) {
if (currentExecIsNSAppRun) {
// The event dispatcher has been interrupted. But since
// [NSApplication run] is running the event loop, we
@@ -903,6 +892,21 @@ void QCocoaEventDispatcherPrivate::processPostedEvents()
}
}
+void QCocoaEventDispatcherPrivate::removeQueuedUserInputEvents(int nsWinNumber)
+{
+ if (nsWinNumber) {
+ int eventIndex = queuedUserInputEvents.size();
+
+ while (--eventIndex >= 0) {
+ NSEvent * nsevent = static_cast<NSEvent *>(queuedUserInputEvents.at(eventIndex));
+ if ([nsevent windowNumber] == nsWinNumber) {
+ queuedUserInputEvents.removeAt(eventIndex);
+ [nsevent release];
+ }
+ }
+ }
+}
+
void QCocoaEventDispatcherPrivate::firstLoopEntry(CFRunLoopObserverRef ref,
CFRunLoopActivity activity,
void *info)
@@ -948,23 +952,16 @@ void QCocoaEventDispatcher::interrupt()
{
Q_D(QCocoaEventDispatcher);
d->interrupt = true;
- if (d->currentModalSessionCached) {
- // If a modal session is active, abort it so that we can clean it up
- // later. We can't use [NSApp stopModal] here, because we do not know
- // where the interrupt() came from.
- [NSApp abortModal];
- } else {
- wakeUp();
-
- // We do nothing more here than setting d->interrupt = true, and
- // poke the event loop if it is sleeping. Actually stopping
- // NSApp, or the current modal session, is done inside the send
- // posted events callback. We do this to ensure that all current pending
- // cocoa events gets delivered before we stop. Otherwise, if we now stop
- // the last event loop recursion, cocoa will just drop pending posted
- // events on the floor before we get a chance to reestablish a new session.
- d->cancelWaitForMoreEvents();
- }
+ wakeUp();
+
+ // We do nothing more here than setting d->interrupt = true, and
+ // poke the event loop if it is sleeping. Actually stopping
+ // NSApp, or the current modal session, is done inside the send
+ // posted events callback. We do this to ensure that all current pending
+ // cocoa events gets delivered before we stop. Otherwise, if we now stop
+ // the last event loop recursion, cocoa will just drop pending posted
+ // events on the floor before we get a chance to reestablish a new session.
+ d->cancelWaitForMoreEvents();
}
void QCocoaEventDispatcher::flush()
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.h b/src/plugins/platforms/cocoa/qcocoaintegration.h
index 9c4f86d893..07b73c1a7a 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.h
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.h
@@ -139,8 +139,6 @@ public:
void setToolbar(QWindow *window, NSToolbar *toolbar);
NSToolbar *toolbar(QWindow *window) const;
void clearToolbars();
- void setWindow(NSWindow* nsWindow, QCocoaWindow *window);
- QCocoaWindow *window(NSWindow *window);
private:
static QCocoaIntegration *mInstance;
@@ -159,7 +157,6 @@ private:
QScopedPointer<QCocoaKeyMapper> mKeyboardMapper;
QHash<QWindow *, NSToolbar *> mToolbars;
- QHash<NSWindow *, QCocoaWindow*> mWindows;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm
index e7a973e45b..8723b20615 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.mm
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm
@@ -159,9 +159,12 @@ qreal QCocoaScreen::devicePixelRatio() const
QWindow *QCocoaScreen::topLevelAt(const QPoint &point) const
{
// Get a z-ordered list of windows. Iterate through it until
- // we find a window which contains the point.
+ // we find a (Qt) window which contains the point.
for (NSWindow *nsWindow in [NSApp orderedWindows]) {
- QCocoaWindow *cocoaWindow = QCocoaIntegration::instance()->window(nsWindow);
+ if (![nsWindow isKindOfClass:[QNSWindow class]])
+ continue;
+ QNSWindow *qnsWindow = static_cast<QNSWindow *>(nsWindow);
+ QCocoaWindow *cocoaWindow = qnsWindow.helper.platformWindow;
if (!cocoaWindow)
continue;
QWindow *window = cocoaWindow->window();
@@ -517,16 +520,6 @@ NSToolbar *QCocoaIntegration::toolbar(QWindow *window) const
return mToolbars.value(window);
}
-void QCocoaIntegration::setWindow(NSWindow* nsWindow, QCocoaWindow *window)
-{
- mWindows.insert(nsWindow, window);
-}
-
-QCocoaWindow *QCocoaIntegration::window(NSWindow *window)
-{
- return mWindows.value(window);
-}
-
void QCocoaIntegration::clearToolbars()
{
QHash<QWindow *, NSToolbar *>::const_iterator it = mToolbars.constBegin();
diff --git a/src/plugins/platforms/cocoa/qcocoamenuloader.mm b/src/plugins/platforms/cocoa/qcocoamenuloader.mm
index 60bc3b5a55..9340e945fb 100644
--- a/src/plugins/platforms/cocoa/qcocoamenuloader.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenuloader.mm
@@ -174,7 +174,7 @@ QT_END_NAMESPACE
- (void)removeActionsFromAppMenu
{
for (NSMenuItem *item in [appMenu itemArray])
- [item setTag:nil];
+ [item setTag:0];
}
- (void)dealloc
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index 651fedb26e..c8ca494b33 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -182,13 +182,22 @@ static bool isMouseEvent(NSEvent *ev)
- (void)detachFromPlatformWindow
{
+ _platformWindow = 0;
[self.window.delegate release];
self.window.delegate = nil;
}
- (void)clearWindow
{
- _window = nil;
+ if (_window) {
+ QCocoaEventDispatcher *cocoaEventDispatcher = qobject_cast<QCocoaEventDispatcher *>(QGuiApplication::instance()->eventDispatcher());
+ if (cocoaEventDispatcher) {
+ QCocoaEventDispatcherPrivate *cocoaEventDispatcherPrivate = static_cast<QCocoaEventDispatcherPrivate *>(QObjectPrivate::get(cocoaEventDispatcher));
+ cocoaEventDispatcherPrivate->removeQueuedUserInputEvents([_window windowNumber]);
+ }
+
+ _window = nil;
+ }
}
- (void)dealloc
@@ -261,8 +270,6 @@ static bool isMouseEvent(NSEvent *ev)
{
[self close];
- QCocoaIntegration::instance()->setWindow(self, 0);
-
if (self.helper.grabbingMouse) {
self.helper.releaseOnMouseUp = YES;
} else {
@@ -329,7 +336,6 @@ static bool isMouseEvent(NSEvent *ev)
{
[self.helper detachFromPlatformWindow];
[self close];
- QCocoaIntegration::instance()->setWindow(self, 0);
[self release];
}
@@ -1001,9 +1007,14 @@ bool QCocoaWindow::isExposed() const
bool QCocoaWindow::isOpaque() const
{
+ // OpenGL surfaces can be ordered either above(default) or below the NSWindow.
+ // When ordering below the window must be tranclucent.
+ static GLint openglSourfaceOrder = qt_mac_resolveOption(1, "QT_MAC_OPENGL_SURFACE_ORDER");
+
bool translucent = (window()->format().alphaBufferSize() > 0
|| window()->opacity() < 1
- || (m_qtView && [m_qtView hasMask]));
+ || (m_qtView && [m_qtView hasMask]))
+ || (surface()->supportsOpenGL() && openglSourfaceOrder == -1);
return !translucent;
}
@@ -1404,7 +1415,13 @@ QCocoaNSWindow * QCocoaWindow::createNSWindow()
NSInteger level = windowLevel(flags);
[createdWindow setLevel:level];
- if (window()->format().alphaBufferSize() > 0) {
+ // OpenGL surfaces can be ordered either above(default) or below the NSWindow.
+ // When ordering below the window must be tranclucent and have a clear background color.
+ static GLint openglSourfaceOrder = qt_mac_resolveOption(1, "QT_MAC_OPENGL_SURFACE_ORDER");
+
+ bool isTranslucent = window()->format().alphaBufferSize() > 0
+ || (surface()->supportsOpenGL() && openglSourfaceOrder == -1);
+ if (isTranslucent) {
[createdWindow setBackgroundColor:[NSColor clearColor]];
[createdWindow setOpaque:NO];
}
@@ -1413,8 +1430,6 @@ QCocoaNSWindow * QCocoaWindow::createNSWindow()
applyContentBorderThickness(createdWindow);
- QCocoaIntegration::instance()->setWindow(createdWindow, this);
-
return createdWindow;
}
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.cpp
index fb47851a06..f2400cf8fc 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.cpp
@@ -64,6 +64,7 @@ public:
}
Q_ASSERT(deviceContext);
+ deviceContext->SetUnitMode(D2D1_UNIT_MODE_PIXELS);
}
void begin()
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp
index a838950c9e..4c39560cbe 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp
@@ -211,118 +211,16 @@ private:
bool m_roundCoordinates;
};
-static ComPtr<ID2D1PathGeometry1> painterPathToID2D1PathGeometry(const QPainterPath &path, bool alias)
-{
- Direct2DPathGeometryWriter writer;
- if (!writer.begin())
- return NULL;
-
- writer.setWindingFillEnabled(path.fillRule() == Qt::WindingFill);
- writer.setAliasingEnabled(alias);
-
- for (int i = 0; i < path.elementCount(); i++) {
- const QPainterPath::Element element = path.elementAt(i);
-
- switch (element.type) {
- case QPainterPath::MoveToElement:
- writer.moveTo(element);
- break;
-
- case QPainterPath::LineToElement:
- writer.lineTo(element);
- break;
-
- case QPainterPath::CurveToElement:
- {
- const QPainterPath::Element data1 = path.elementAt(++i);
- const QPainterPath::Element data2 = path.elementAt(++i);
-
- Q_ASSERT(i < path.elementCount());
-
- Q_ASSERT(data1.type == QPainterPath::CurveToDataElement);
- Q_ASSERT(data2.type == QPainterPath::CurveToDataElement);
-
- writer.curveTo(element, data1, data2);
- }
- break;
-
- case QPainterPath::CurveToDataElement:
- qWarning("%s: Unhandled Curve Data Element", __FUNCTION__);
- break;
- }
+struct D2DVectorPathCache {
+ ComPtr<ID2D1PathGeometry1> aliased;
+ ComPtr<ID2D1PathGeometry1> antiAliased;
+
+ static void cleanup_func(QPaintEngineEx *engine, void *data) {
+ Q_UNUSED(engine);
+ D2DVectorPathCache *e = static_cast<D2DVectorPathCache *>(data);
+ delete e;
}
-
- writer.close();
- return writer.geometry();
-}
-
-static ComPtr<ID2D1PathGeometry1> vectorPathToID2D1PathGeometry(const QVectorPath &path, bool alias)
-{
- Direct2DPathGeometryWriter writer;
- if (!writer.begin())
- return NULL;
-
- writer.setWindingFillEnabled(path.hasWindingFill());
- writer.setAliasingEnabled(alias);
-
- const QPainterPath::ElementType *types = path.elements();
- const int count = path.elementCount();
- const qreal *points = path.points();
-
- Q_ASSERT(points);
-
- if (types) {
- qreal x, y;
-
- for (int i = 0; i < count; i++) {
- x = points[i * 2];
- y = points[i * 2 + 1];
-
- switch (types[i]) {
- case QPainterPath::MoveToElement:
- writer.moveTo(QPointF(x, y));
- break;
-
- case QPainterPath::LineToElement:
- writer.lineTo(QPointF(x, y));
- break;
-
- case QPainterPath::CurveToElement:
- {
- Q_ASSERT((i + 2) < count);
- Q_ASSERT(types[i+1] == QPainterPath::CurveToDataElement);
- Q_ASSERT(types[i+2] == QPainterPath::CurveToDataElement);
-
- i++;
- const qreal x2 = points[i * 2];
- const qreal y2 = points[i * 2 + 1];
-
- i++;
- const qreal x3 = points[i * 2];
- const qreal y3 = points[i * 2 + 1];
-
- writer.curveTo(QPointF(x, y), QPointF(x2, y2), QPointF(x3, y3));
- }
- break;
-
- case QPainterPath::CurveToDataElement:
- qWarning("%s: Unhandled Curve Data Element", __FUNCTION__);
- break;
- }
- }
- } else {
- writer.moveTo(QPointF(points[0], points[1]));
- for (int i = 1; i < count; i++)
- writer.lineTo(QPointF(points[i * 2], points[i * 2 + 1]));
- }
-
- if (writer.isInFigure())
- if (path.hasImplicitClose())
- writer.lineTo(QPointF(points[0], points[1]));
-
- writer.close();
- return writer.geometry();
-}
+};
class QWindowsDirect2DPaintEnginePrivate : public QPaintEngineExPrivate
{
@@ -426,7 +324,7 @@ public:
dc()->PushAxisAlignedClip(rect, antialiasMode());
pushedClips.push(AxisAlignedClip);
} else {
- ComPtr<ID2D1PathGeometry1> geometry = vectorPathToID2D1PathGeometry(path, antialiasMode() == D2D1_ANTIALIAS_MODE_ALIASED);
+ ComPtr<ID2D1PathGeometry1> geometry = vectorPathToID2D1PathGeometry(path);
if (!geometry) {
qWarning("%s: Could not convert vector path to painter path!", __FUNCTION__);
return;
@@ -571,6 +469,7 @@ public:
break;
case Qt::RoundCap:
props.startCap = props.endCap = props.dashCap = D2D1_CAP_STYLE_ROUND;
+ break;
case Qt::FlatCap:
default:
props.startCap = props.endCap = props.dashCap = D2D1_CAP_STYLE_FLAT;
@@ -835,6 +734,104 @@ public:
return result;
}
+ ComPtr<ID2D1PathGeometry1> vectorPathToID2D1PathGeometry(const QVectorPath &path)
+ {
+ Q_Q(QWindowsDirect2DPaintEngine);
+
+ const bool alias = !q->antiAliasingEnabled();
+
+ QVectorPath::CacheEntry *cacheEntry = path.isCacheable() ? path.lookupCacheData(q)
+ : Q_NULLPTR;
+
+ if (cacheEntry) {
+ D2DVectorPathCache *e = static_cast<D2DVectorPathCache *>(cacheEntry->data);
+ if (alias && e->aliased)
+ return e->aliased;
+ else if (!alias && e->antiAliased)
+ return e->antiAliased;
+ }
+
+ Direct2DPathGeometryWriter writer;
+ if (!writer.begin())
+ return NULL;
+
+ writer.setWindingFillEnabled(path.hasWindingFill());
+ writer.setAliasingEnabled(alias);
+
+ const QPainterPath::ElementType *types = path.elements();
+ const int count = path.elementCount();
+ const qreal *points = path.points();
+
+ Q_ASSERT(points);
+
+ if (types) {
+ qreal x, y;
+
+ for (int i = 0; i < count; i++) {
+ x = points[i * 2];
+ y = points[i * 2 + 1];
+
+ switch (types[i]) {
+ case QPainterPath::MoveToElement:
+ writer.moveTo(QPointF(x, y));
+ break;
+
+ case QPainterPath::LineToElement:
+ writer.lineTo(QPointF(x, y));
+ break;
+
+ case QPainterPath::CurveToElement:
+ {
+ Q_ASSERT((i + 2) < count);
+ Q_ASSERT(types[i+1] == QPainterPath::CurveToDataElement);
+ Q_ASSERT(types[i+2] == QPainterPath::CurveToDataElement);
+
+ i++;
+ const qreal x2 = points[i * 2];
+ const qreal y2 = points[i * 2 + 1];
+
+ i++;
+ const qreal x3 = points[i * 2];
+ const qreal y3 = points[i * 2 + 1];
+
+ writer.curveTo(QPointF(x, y), QPointF(x2, y2), QPointF(x3, y3));
+ }
+ break;
+
+ case QPainterPath::CurveToDataElement:
+ qWarning("%s: Unhandled Curve Data Element", __FUNCTION__);
+ break;
+ }
+ }
+ } else {
+ writer.moveTo(QPointF(points[0], points[1]));
+ for (int i = 1; i < count; i++)
+ writer.lineTo(QPointF(points[i * 2], points[i * 2 + 1]));
+ }
+
+ if (writer.isInFigure())
+ if (path.hasImplicitClose())
+ writer.lineTo(QPointF(points[0], points[1]));
+
+ writer.close();
+ ComPtr<ID2D1PathGeometry1> geometry = writer.geometry();
+
+ if (path.isCacheable()) {
+ if (!cacheEntry)
+ cacheEntry = path.addCacheData(q, new D2DVectorPathCache, D2DVectorPathCache::cleanup_func);
+
+ D2DVectorPathCache *e = static_cast<D2DVectorPathCache *>(cacheEntry->data);
+ if (alias)
+ e->aliased = geometry;
+ else
+ e->antiAliased = geometry;
+ } else {
+ path.makeCacheable();
+ }
+
+ return geometry;
+ }
+
void updateHints()
{
dc()->SetAntialiasMode(antialiasMode());
@@ -871,7 +868,7 @@ bool QWindowsDirect2DPaintEngine::begin(QPaintDevice * pdev)
QPainterPath p;
p.addRegion(systemClip());
- ComPtr<ID2D1PathGeometry1> geometry = painterPathToID2D1PathGeometry(p, d->antialiasMode() == D2D1_ANTIALIAS_MODE_ALIASED);
+ ComPtr<ID2D1PathGeometry1> geometry = d->vectorPathToID2D1PathGeometry(qtVectorPathForPath(p));
if (!geometry)
return false;
@@ -938,7 +935,7 @@ void QWindowsDirect2DPaintEngine::draw(const QVectorPath &path)
{
Q_D(QWindowsDirect2DPaintEngine);
- ComPtr<ID2D1Geometry> geometry = vectorPathToID2D1PathGeometry(path, d->antialiasMode() == D2D1_ANTIALIAS_MODE_ALIASED);
+ ComPtr<ID2D1Geometry> geometry = d->vectorPathToID2D1PathGeometry(path);
if (!geometry) {
qWarning("%s: Could not convert path to d2d geometry", __FUNCTION__);
return;
@@ -978,7 +975,7 @@ void QWindowsDirect2DPaintEngine::fill(const QVectorPath &path, const QBrush &br
if (!d->brush.brush)
return;
- ComPtr<ID2D1Geometry> geometry = vectorPathToID2D1PathGeometry(path, d->antialiasMode() == D2D1_ANTIALIAS_MODE_ALIASED);
+ ComPtr<ID2D1Geometry> geometry = d->vectorPathToID2D1PathGeometry(path);
if (!geometry) {
qWarning("%s: Could not convert path to d2d geometry", __FUNCTION__);
return;
@@ -1016,7 +1013,7 @@ void QWindowsDirect2DPaintEngine::stroke(const QVectorPath &path, const QPen &pe
if (!d->pen.brush)
return;
- ComPtr<ID2D1Geometry> geometry = vectorPathToID2D1PathGeometry(path, d->antialiasMode() == D2D1_ANTIALIAS_MODE_ALIASED);
+ ComPtr<ID2D1Geometry> geometry = d->vectorPathToID2D1PathGeometry(path);
if (!geometry) {
qWarning("%s: Could not convert path to d2d geometry", __FUNCTION__);
return;
@@ -1163,6 +1160,25 @@ void QWindowsDirect2DPaintEngine::drawRects(const QRectF *rects, int rectCount)
}
}
+static bool isLinePositivelySloped(const QPointF &p1, const QPointF &p2)
+{
+ if (p2.x() > p1.x())
+ return p2.y() < p1.y();
+
+ if (p1.x() > p2.x())
+ return p1.y() < p2.y();
+
+ return false;
+}
+
+static void adjustLine(QPointF *p1, QPointF *p2)
+{
+ if (isLinePositivelySloped(*p1, *p2)) {
+ p1->ry() -= qreal(1.0);
+ p2->ry() -= qreal(1.0);
+ }
+}
+
void QWindowsDirect2DPaintEngine::drawLines(const QLine *lines, int lineCount)
{
Q_D(QWindowsDirect2DPaintEngine);
@@ -1184,6 +1200,10 @@ void QWindowsDirect2DPaintEngine::drawLines(const QLine *lines, int lineCount)
continue;
}
+ // Match raster engine output
+ if (!antiAliasingEnabled())
+ adjustLine(&p1, &p2);
+
adjustForAliasing(&p1);
adjustForAliasing(&p2);
@@ -1216,6 +1236,10 @@ void QWindowsDirect2DPaintEngine::drawLines(const QLineF *lines, int lineCount)
continue;
}
+ // Match raster engine output
+ if (!antiAliasingEnabled())
+ adjustLine(&p1, &p2);
+
adjustForAliasing(&p1);
adjustForAliasing(&p2);
@@ -1468,29 +1492,27 @@ void QWindowsDirect2DPaintEngine::drawTextItem(const QPointF &p, const QTextItem
rtl);
}
-// Points (1/72 inches) to Microsoft's Device Independent Pixels (1/96 inches)
-inline static Q_DECL_CONSTEXPR FLOAT pointSizeToDIP(qreal pointSize)
+inline static FLOAT pointSizeToDIP(qreal pointSize, FLOAT dpiY)
{
- return pointSize + (pointSize / qreal(3.0));
+ return (pointSize + (pointSize / qreal(3.0))) * (dpiY / 96.0f);
}
-inline static FLOAT pixelSizeToDIP(int pixelSize)
+inline static FLOAT pixelSizeToDIP(int pixelSize, FLOAT dpiY)
{
- FLOAT dpiX, dpiY;
- factory()->GetDesktopDpi(&dpiX, &dpiY);
-
- return FLOAT(pixelSize) / (dpiY / 96.0f);
+ return FLOAT(pixelSize) * 96.0f / dpiY;
}
inline static FLOAT fontSizeInDIP(const QFont &font)
{
- // Direct2d wants the font size in DIPs (Device Independent Pixels), each of which is 1/96 inches.
+ FLOAT dpiX, dpiY;
+ QWindowsDirect2DContext::instance()->d2dFactory()->GetDesktopDpi(&dpiX, &dpiY);
+
if (font.pixelSize() == -1) {
// font size was set as points
- return pointSizeToDIP(font.pointSizeF());
+ return pointSizeToDIP(font.pointSizeF(), dpiY);
} else {
// font size was set as pixels
- return pixelSizeToDIP(font.pixelSize());
+ return pixelSizeToDIP(font.pixelSize(), dpiY);
}
}
diff --git a/src/plugins/platforms/ios/quiview_textinput.mm b/src/plugins/platforms/ios/quiview_textinput.mm
index 79e3897013..03006b3f99 100644
--- a/src/plugins/platforms/ios/quiview_textinput.mm
+++ b/src/plugins/platforms/ios/quiview_textinput.mm
@@ -495,14 +495,14 @@ Q_GLOBAL_STATIC(StaticVariables, staticVariables);
return;
if ([text isEqualToString:@"\n"]) {
+ if (self.returnKeyType == UIReturnKeyDone)
+ qApp->inputMethod()->hide();
+
QKeyEvent press(QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier);
QKeyEvent release(QEvent::KeyRelease, Qt::Key_Return, Qt::NoModifier);
[self sendEventToFocusObject:press];
[self sendEventToFocusObject:release];
- if (self.returnKeyType == UIReturnKeyDone)
- [self resignFirstResponder];
-
return;
}
diff --git a/src/plugins/platforms/qnx/qqnxnativeinterface.cpp b/src/plugins/platforms/qnx/qqnxnativeinterface.cpp
index a245a0c43a..05504f8bf4 100644
--- a/src/plugins/platforms/qnx/qqnxnativeinterface.cpp
+++ b/src/plugins/platforms/qnx/qqnxnativeinterface.cpp
@@ -41,7 +41,10 @@
#include "qqnxnativeinterface.h"
+#if !defined(QT_NO_OPENGL)
#include "qqnxglcontext.h"
+#endif
+
#include "qqnxscreen.h"
#include "qqnxwindow.h"
#if defined(QQNX_IMF)
@@ -50,7 +53,10 @@
#include "qqnxintegration.h"
+#if !defined(QT_NO_OPENGL)
#include <QtGui/QOpenGLContext>
+#endif
+
#include <QtGui/QScreen>
#include <QtGui/QWindow>
@@ -95,6 +101,7 @@ void *QQnxNativeInterface::nativeResourceForIntegration(const QByteArray &resour
return 0;
}
+#if !defined(QT_NO_OPENGL)
void *QQnxNativeInterface::nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context)
{
if (resource == "eglcontext" && context)
@@ -102,6 +109,7 @@ void *QQnxNativeInterface::nativeResourceForContext(const QByteArray &resource,
return 0;
}
+#endif
void QQnxNativeInterface::setWindowProperty(QPlatformWindow *window, const QString &name, const QVariant &value)
{
diff --git a/src/plugins/platforms/qnx/qqnxnativeinterface.h b/src/plugins/platforms/qnx/qqnxnativeinterface.h
index 83900791f6..41e6105f84 100644
--- a/src/plugins/platforms/qnx/qqnxnativeinterface.h
+++ b/src/plugins/platforms/qnx/qqnxnativeinterface.h
@@ -56,7 +56,10 @@ public:
void *nativeResourceForScreen(const QByteArray &resource, QScreen *screen);
void *nativeResourceForIntegration(const QByteArray &resource);
+#if !defined(QT_NO_OPENGL)
void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context);
+#endif
+
void setWindowProperty(QPlatformWindow *window, const QString &name, const QVariant &value);
NativeResourceForIntegrationFunction nativeResourceFunctionForIntegration(const QByteArray &resource);
diff --git a/src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp b/src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp
index 3109388fb2..7ae042cb50 100644
--- a/src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp
+++ b/src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp
@@ -170,7 +170,7 @@ void QQnxRasterBackingStore::beginPaint(const QRegion &region)
platformWindow()->adjustBufferSize();
- if (window()->requestedFormat().alphaBufferSize() != 0) {
+ if (window()->requestedFormat().alphaBufferSize() > 0) {
foreach (const QRect &r, region.rects()) {
// Clear transparent regions
const int bg[] = {
@@ -185,8 +185,8 @@ void QQnxRasterBackingStore::beginPaint(const QRegion &region)
platformWindow()->renderBuffer().nativeBuffer(), bg),
"failed to clear transparent regions");
}
- Q_SCREEN_CHECKERROR(screen_flush_blits(platformWindow()->screen()->nativeContext(), 0),
- "failed to flush blits");
+ Q_SCREEN_CHECKERROR(screen_flush_blits(platformWindow()->screen()->nativeContext(),
+ SCREEN_WAIT_IDLE), "failed to flush blits");
}
}
diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
index f081bbd307..e4d60d6ec8 100644
--- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
+++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
@@ -164,15 +164,18 @@ namespace {
{
Q_ASSERT(tagName.size() == 4);
quint32 tagId = *(reinterpret_cast<const quint32 *>(tagName.constData()));
-
- if (m_fontData.size() < sizeof(OffsetSubTable) + sizeof(TableDirectory))
+ if (Q_UNLIKELY(m_fontData.size() < sizeof(OffsetSubTable)))
return 0;
OffsetSubTable *offsetSubTable = reinterpret_cast<OffsetSubTable *>(m_fontData.data());
TableDirectory *tableDirectory = reinterpret_cast<TableDirectory *>(offsetSubTable + 1);
+ quint16 tableCount = qFromBigEndian<quint16>(offsetSubTable->numTables);
+ if (Q_UNLIKELY(quint32(m_fontData.size()) < sizeof(OffsetSubTable) + sizeof(TableDirectory) * tableCount))
+ return 0;
+
TableDirectory *nameTableDirectoryEntry = 0;
- for (int i = 0; i < qFromBigEndian<quint16>(offsetSubTable->numTables); ++i, ++tableDirectory) {
+ for (int i = 0; i < tableCount; ++i, ++tableDirectory) {
if (tableDirectory->identifier == tagId) {
nameTableDirectoryEntry = tableDirectory;
break;
@@ -190,19 +193,34 @@ namespace {
nameTableDirectoryEntry = tableDirectoryEntry("name");
if (nameTableDirectoryEntry != 0) {
- NameTable *nameTable = reinterpret_cast<NameTable *>(
- m_fontData.data() + qFromBigEndian<quint32>(nameTableDirectoryEntry->offset));
+ quint32 offset = qFromBigEndian<quint32>(nameTableDirectoryEntry->offset);
+ if (Q_UNLIKELY(quint32(m_fontData.size()) < offset + sizeof(NameTable)))
+ return QString();
+
+ NameTable *nameTable = reinterpret_cast<NameTable *>(m_fontData.data() + offset);
NameRecord *nameRecord = reinterpret_cast<NameRecord *>(nameTable + 1);
- for (int i = 0; i < qFromBigEndian<quint16>(nameTable->count); ++i, ++nameRecord) {
+
+ quint16 nameTableCount = qFromBigEndian<quint16>(nameTable->count);
+ if (Q_UNLIKELY(quint32(m_fontData.size()) < offset + sizeof(NameRecord) * nameTableCount))
+ return QString();
+
+ for (int i = 0; i < nameTableCount; ++i, ++nameRecord) {
if (qFromBigEndian<quint16>(nameRecord->nameID) == 1
&& qFromBigEndian<quint16>(nameRecord->platformID) == 3 // Windows
&& qFromBigEndian<quint16>(nameRecord->languageID) == 0x0409) { // US English
+ quint16 stringOffset = qFromBigEndian<quint16>(nameTable->stringOffset);
+ quint16 nameOffset = qFromBigEndian<quint16>(nameRecord->offset);
+ quint16 nameLength = qFromBigEndian<quint16>(nameRecord->length);
+
+ if (Q_UNLIKELY(quint32(m_fontData.size()) < offset + stringOffset + nameOffset + nameLength))
+ return QString();
+
const void *ptr = reinterpret_cast<const quint8 *>(nameTable)
- + qFromBigEndian<quint16>(nameTable->stringOffset)
- + qFromBigEndian<quint16>(nameRecord->offset);
+ + stringOffset
+ + nameOffset;
const quint16 *s = reinterpret_cast<const quint16 *>(ptr);
- const quint16 *e = s + qFromBigEndian<quint16>(nameRecord->length) / sizeof(quint16);
+ const quint16 *e = s + nameLength / sizeof(quint16);
while (s != e)
name += QChar( qFromBigEndian<quint16>(*s++));
break;
diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.cpp b/src/plugins/platforms/windows/qwindowsmousehandler.cpp
index 5c9add4baa..cc0597b72d 100644
--- a/src/plugins/platforms/windows/qwindowsmousehandler.cpp
+++ b/src/plugins/platforms/windows/qwindowsmousehandler.cpp
@@ -354,7 +354,6 @@ static bool isValidWheelReceiver(QWindow *candidate)
bool QWindowsMouseHandler::translateMouseWheelEvent(QWindow *window, HWND,
MSG msg, LRESULT *)
{
- const Qt::MouseButtons buttons = keyStateToMouseButtons((int)msg.wParam);
const Qt::KeyboardModifiers mods = keyStateToModifiers((int)msg.wParam);
int delta;
diff --git a/src/plugins/platforms/windows/qwindowstabletsupport.cpp b/src/plugins/platforms/windows/qwindowstabletsupport.cpp
index 484ed9cb05..2a1e5c58b9 100644
--- a/src/plugins/platforms/windows/qwindowstabletsupport.cpp
+++ b/src/plugins/platforms/windows/qwindowstabletsupport.cpp
@@ -458,8 +458,8 @@ bool QWindowsTabletSupport::translateTabletPacketEvent()
// Z = sin(altitude)
// X Tilt = arctan(X / Z)
// Y Tilt = arctan(Y / Z)
- const double radAzim = (packet.pkOrientation.orAzimuth / 10) * (M_PI / 180);
- const double tanAlt = tan((abs(packet.pkOrientation.orAltitude / 10)) * (M_PI / 180));
+ const double radAzim = (packet.pkOrientation.orAzimuth / 10.0) * (M_PI / 180);
+ const double tanAlt = tan((abs(packet.pkOrientation.orAltitude / 10.0)) * (M_PI / 180));
const double degX = atan(sin(radAzim) / tanAlt);
const double degY = atan(cos(radAzim) / tanAlt);
diff --git a/src/plugins/platforms/winrt/qwinrtbackingstore.cpp b/src/plugins/platforms/winrt/qwinrtbackingstore.cpp
index 9b623048af..b8418eef6a 100644
--- a/src/plugins/platforms/winrt/qwinrtbackingstore.cpp
+++ b/src/plugins/platforms/winrt/qwinrtbackingstore.cpp
@@ -284,7 +284,7 @@ QWinRTBackingStore::~QWinRTBackingStore()
QPaintDevice *QWinRTBackingStore::paintDevice()
{
- return m_paintDevice.data();
+ return &m_paintDevice;
}
void QWinRTBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
@@ -293,8 +293,6 @@ void QWinRTBackingStore::flush(QWindow *window, const QRegion &region, const QPo
if (m_size.isEmpty())
return;
- const QImage *image = static_cast<QImage *>(m_paintDevice.data());
-
m_context->makeCurrent(window);
// Blitting the entire image width trades zero image copy/relayout for a larger texture upload.
@@ -307,7 +305,7 @@ void QWinRTBackingStore::flush(QWindow *window, const QRegion &region, const QPo
glBindTexture(GL_TEXTURE_2D, m_texture);
QRect bounds = region.boundingRect();
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, bounds.y(), m_size.width(), bounds.height(),
- GL_BGRA_EXT, GL_UNSIGNED_BYTE, image->scanLine(bounds.y()));
+ GL_BGRA_EXT, GL_UNSIGNED_BYTE, m_paintDevice.constScanLine(bounds.y()));
// TODO: Implement GL_EXT_unpack_subimage in ANGLE for more minimal uploads
//glPixelStorei(GL_UNPACK_ROW_LENGTH, image->bytesPerLine());
//glTexSubImage2D(GL_TEXTURE_2D, 0, bounds.x(), bounds.y(), bounds.width(), bounds.height(),
@@ -325,7 +323,8 @@ void QWinRTBackingStore::flush(QWindow *window, const QRegion &region, const QPo
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, quadCoords);
// Render
- glViewport(0, 0, m_size.width(), m_size.height());
+ const QSize blitSize = m_size * window->devicePixelRatio();
+ glViewport(0, 0, blitSize.width(), blitSize.height());
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
// Unbind
@@ -338,8 +337,8 @@ void QWinRTBackingStore::flush(QWindow *window, const QRegion &region, const QPo
// fast blit - TODO: perform the blit inside swap buffers instead
glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, m_fbo);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, 0);
- glBlitFramebufferANGLE(0, 0, m_size.width(), m_size.height(), // TODO: blit only the changed rectangle
- 0, 0, m_size.width(), m_size.height(),
+ glBlitFramebufferANGLE(0, 0, blitSize.width(), blitSize.height(), // TODO: blit only the changed rectangle
+ 0, 0, blitSize.width(), blitSize.height(),
GL_COLOR_BUFFER_BIT, GL_NEAREST);
m_context->swapBuffers(window);
@@ -359,21 +358,22 @@ void QWinRTBackingStore::resize(const QSize &size, const QRegion &staticContents
if (m_size.isEmpty())
return;
- m_paintDevice.reset(new QImage(m_size, QImage::Format_ARGB32_Premultiplied));
+ m_paintDevice = QImage(m_size, QImage::Format_ARGB32_Premultiplied);
m_context->makeCurrent(window());
// Input texture
glBindTexture(GL_TEXTURE_2D, m_texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, m_size.width(), m_size.height(),
0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, NULL);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindTexture(GL_TEXTURE_2D, 0);
// Render buffer
glBindRenderbuffer(GL_RENDERBUFFER, m_rbo);
- glRenderbufferStorage(GL_RENDERBUFFER, GL_BGRA8_EXT, m_size.width(), m_size.height());
+ const QSize blitSize = m_size * window()->devicePixelRatio();
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_BGRA8_EXT, blitSize.width(), blitSize.height());
glBindRenderbuffer(GL_RENDERBUFFER, 0);
m_context->doneCurrent();
}
diff --git a/src/plugins/platforms/winrt/qwinrtbackingstore.h b/src/plugins/platforms/winrt/qwinrtbackingstore.h
index 726f7c838f..f00fa85a26 100644
--- a/src/plugins/platforms/winrt/qwinrtbackingstore.h
+++ b/src/plugins/platforms/winrt/qwinrtbackingstore.h
@@ -60,18 +60,19 @@ public:
void endPaint();
void flush(QWindow *window, const QRegion &region, const QPoint &offset);
void resize(const QSize &size, const QRegion &staticContents);
+ QImage toImage() const Q_DECL_OVERRIDE { return m_paintDevice; }
private:
bool initialize();
bool m_initialized;
QSize m_size;
- QScopedPointer<QPaintDevice> m_paintDevice;
QScopedPointer<QOpenGLContext> m_context;
quint32 m_shaderProgram;
quint32 m_fbo;
quint32 m_rbo;
quint32 m_texture;
QWinRTScreen *m_screen;
+ QImage m_paintDevice;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtcursor.cpp b/src/plugins/platforms/winrt/qwinrtcursor.cpp
index 8241560cef..f09454ebc3 100644
--- a/src/plugins/platforms/winrt/qwinrtcursor.cpp
+++ b/src/plugins/platforms/winrt/qwinrtcursor.cpp
@@ -135,6 +135,8 @@ void QWinRTCursor::changeCursor(QCursor *windowCursor, QWindow *)
ICoreCursor *cursor;
if (SUCCEEDED(m_cursorFactory->CreateCursor(type, 0, &cursor)))
m_window->put_PointerCursor(cursor);
+#else // Q_OS_WINPHONE
+ Q_UNUSED(windowCursor)
#endif // Q_OS_WINPHONE
}
#endif // QT_NO_CURSOR
diff --git a/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp b/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp
index 70bb9469db..f4e1fbe533 100644
--- a/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp
+++ b/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp
@@ -44,13 +44,13 @@
#include <QtCore/QCoreApplication>
#include <QtCore/QFile>
-#ifndef Q_OS_WINPHONE
+#ifdef QT_WINRT_USE_DWRITE
#include <QtCore/QUuid>
#include <QtGui/private/qfontengine_ft_p.h>
#include <dwrite_1.h>
#include <wrl.h>
using namespace Microsoft::WRL;
-#endif // !Q_OS_WINPHONE
+#endif // QT_WINRT_USE_DWRITE
QT_BEGIN_NAMESPACE
@@ -62,7 +62,7 @@ QString QWinRTFontDatabase::fontDir() const
const QString applicationDirPath = QCoreApplication::applicationDirPath();
fontDirectory = applicationDirPath + QLatin1String("/fonts");
if (!QFile::exists(fontDirectory)) {
-#ifndef Q_OS_WINPHONE
+#ifdef QT_WINRT_USE_DWRITE
if (m_fontFamilies.isEmpty())
#endif
qWarning("No fonts directory found in application package.");
@@ -72,7 +72,7 @@ QString QWinRTFontDatabase::fontDir() const
return fontDirectory;
}
-#ifndef Q_OS_WINPHONE
+#ifdef QT_WINRT_USE_DWRITE
QWinRTFontDatabase::~QWinRTFontDatabase()
{
@@ -398,6 +398,13 @@ void QWinRTFontDatabase::releaseHandle(void *handle)
QBasicFontDatabase::releaseHandle(handle);
}
-#endif // !Q_OS_WINPHONE
+#else // QT_WINRT_USE_DWRITE
+
+QFont QWinRTFontDatabase::defaultFont() const
+{
+ return QFont(QFontDatabase().families().value(0));
+}
+
+#endif // !QT_WINRT_USE_DWRITE
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtfontdatabase.h b/src/plugins/platforms/winrt/qwinrtfontdatabase.h
index b318a95502..eabcc83afd 100644
--- a/src/plugins/platforms/winrt/qwinrtfontdatabase.h
+++ b/src/plugins/platforms/winrt/qwinrtfontdatabase.h
@@ -46,7 +46,7 @@
QT_BEGIN_NAMESPACE
-#ifndef Q_OS_WINPHONE
+#ifdef QT_WINRT_USE_DWRITE
struct IDWriteFontFile;
struct IDWriteFontFamily;
@@ -61,9 +61,9 @@ class QWinRTFontDatabase : public QBasicFontDatabase
{
public:
QString fontDir() const;
-#ifndef Q_OS_WINPHONE
- ~QWinRTFontDatabase();
QFont defaultFont() const Q_DECL_OVERRIDE;
+#ifdef QT_WINRT_USE_DWRITE
+ ~QWinRTFontDatabase();
void populateFontDatabase() Q_DECL_OVERRIDE;
void populateFamily(const QString &familyName) Q_DECL_OVERRIDE;
QFontEngine *fontEngine(const QFontDef &fontDef, void *handle) Q_DECL_OVERRIDE;
@@ -71,7 +71,7 @@ public:
private:
QHash<IDWriteFontFile *, FontDescription> m_fonts;
QHash<QString, IDWriteFontFamily *> m_fontFamilies;
-#endif // !Q_OS_WINPHONE
+#endif // QT_WINRT_USE_DWRITE
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtinputcontext.cpp b/src/plugins/platforms/winrt/qwinrtinputcontext.cpp
index bc15f1e448..8e1728dc04 100644
--- a/src/plugins/platforms/winrt/qwinrtinputcontext.cpp
+++ b/src/plugins/platforms/winrt/qwinrtinputcontext.cpp
@@ -52,7 +52,7 @@ using namespace ABI::Windows::Foundation;
using namespace ABI::Windows::UI::ViewManagement;
using namespace ABI::Windows::UI::Core;
-#ifdef Q_OS_WINPHONE
+#if defined(Q_OS_WINPHONE) && _MSC_VER==1700
#include <windows.phone.ui.core.h>
using namespace ABI::Windows::Phone::UI::Core;
#endif
@@ -148,22 +148,73 @@ void QWinRTInputContext::setKeyboardRect(const QRectF rect)
#ifdef Q_OS_WINPHONE
+#if _MSC_VER>1700 // Windows Phone 8.1+
+static HRESULT getInputPane(ComPtr<IInputPane2> *inputPane2)
+{
+ ComPtr<IInputPaneStatics> factory;
+ HRESULT hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_ViewManagement_InputPane).Get(),
+ &factory);
+ if (FAILED(hr)) {
+ qErrnoWarning(hr, "Failed to get input pane factory.");
+ return hr;
+ }
+
+ ComPtr<IInputPane> inputPane;
+ hr = factory->GetForCurrentView(&inputPane);
+ if (FAILED(hr)) {
+ qErrnoWarning(hr, "Failed to get input pane.");
+ return hr;
+ }
+
+ hr = inputPane.As(inputPane2);
+ if (FAILED(hr)) {
+ qErrnoWarning(hr, "Failed to get extended input pane.");
+ return hr;
+ }
+ return hr;
+}
+#endif // _MSC_VER>1700
+
void QWinRTInputContext::showInputPanel()
{
+#if _MSC_VER<=1700 // Windows Phone 8.0
ICoreWindowKeyboardInput *input;
if (SUCCEEDED(m_window->QueryInterface(IID_PPV_ARGS(&input)))) {
input->put_IsKeyboardInputEnabled(true);
input->Release();
}
+#else // _MSC_VER<=1700
+ ComPtr<IInputPane2> inputPane;
+ HRESULT hr = getInputPane(&inputPane);
+ if (FAILED(hr))
+ return;
+
+ boolean success;
+ hr = inputPane->TryShow(&success);
+ if (FAILED(hr))
+ qErrnoWarning(hr, "Failed to show input panel.");
+#endif // _MSC_VER>1700
}
void QWinRTInputContext::hideInputPanel()
{
+#if _MSC_VER<=1700 // Windows Phone 8.0
ICoreWindowKeyboardInput *input;
if (SUCCEEDED(m_window->QueryInterface(IID_PPV_ARGS(&input)))) {
input->put_IsKeyboardInputEnabled(false);
input->Release();
}
+#else // _MSC_VER<=1700
+ ComPtr<IInputPane2> inputPane;
+ HRESULT hr = getInputPane(&inputPane);
+ if (FAILED(hr))
+ return;
+
+ boolean success;
+ hr = inputPane->TryHide(&success);
+ if (FAILED(hr))
+ qErrnoWarning(hr, "Failed to hide input panel.");
+#endif // _MSC_VER>1700
}
#else // Q_OS_WINPHONE
diff --git a/src/plugins/platforms/winrt/qwinrtplatformmessagedialoghelper.cpp b/src/plugins/platforms/winrt/qwinrtplatformmessagedialoghelper.cpp
index e70d06860c..c2f884055d 100644
--- a/src/plugins/platforms/winrt/qwinrtplatformmessagedialoghelper.cpp
+++ b/src/plugins/platforms/winrt/qwinrtplatformmessagedialoghelper.cpp
@@ -171,10 +171,11 @@ void QWinRTPlatformMessageDialogHelper::hide()
HRESULT QWinRTPlatformMessageDialogHelper::onInvoked(ABI::Windows::UI::Popups::IUICommand *command)
{
- HSTRING hLabel;
+ HString hLabel;
UINT32 labelLength;
- command->get_Label(&hLabel);
- QString label = QString::fromWCharArray(::WindowsGetStringRawBuffer(hLabel, &labelLength));
+ command->get_Label(hLabel.GetAddressOf());
+ PCWSTR rawString = hLabel.GetRawBuffer(&labelLength);
+ QString label = QString::fromWCharArray(rawString, labelLength);
int buttonId = -1;
for (int i = QPlatformDialogHelper::FirstButton; i < QPlatformDialogHelper::LastButton; i<<=1) {
if ( options()->standardButtons() & i ) {
diff --git a/src/plugins/platforms/winrt/qwinrtplatformtheme.cpp b/src/plugins/platforms/winrt/qwinrtplatformtheme.cpp
index 2c8d33da84..d4034ec571 100644
--- a/src/plugins/platforms/winrt/qwinrtplatformtheme.cpp
+++ b/src/plugins/platforms/winrt/qwinrtplatformtheme.cpp
@@ -50,25 +50,27 @@ QWinRTPlatformTheme::QWinRTPlatformTheme()
bool QWinRTPlatformTheme::usePlatformNativeDialog(QPlatformTheme::DialogType type) const
{
-#ifndef Q_OS_WINPHONE
+#if !(defined(Q_OS_WINPHONE) && _MSC_VER<=1700)
if (type == QPlatformTheme::MessageDialog)
return true;
-#endif // Q_OS_WINPHONE
+#else
+ Q_UNUSED(type)
+#endif // !(Q_OS_WINPHONE && _MSC_VER<=1700)
return false;
}
QPlatformDialogHelper *QWinRTPlatformTheme::createPlatformDialogHelper(QPlatformTheme::DialogType type) const
{
-#ifndef Q_OS_WINPHONE
+#if !(defined(Q_OS_WINPHONE) && _MSC_VER<=1700)
switch (type) {
case QPlatformTheme::MessageDialog:
return new QWinRTPlatformMessageDialogHelper();
default:
return QPlatformTheme::createPlatformDialogHelper(type);
}
-#else
+#else // !(Q_OS_WINPHONE && _MSC_VER<=1700)
return QPlatformTheme::createPlatformDialogHelper(type);
-#endif // Q_OS_WINPHONE
+#endif // Q_OS_WINPHONE && _MSC_VER<=1700
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp
index e2ff7197aa..f948cf9924 100644
--- a/src/plugins/platforms/winrt/qwinrtscreen.cpp
+++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp
@@ -93,6 +93,11 @@ typedef ITypedEventHandler<CoreWindow*, PointerEventArgs*> PointerHandler;
typedef ITypedEventHandler<CoreWindow*, WindowSizeChangedEventArgs*> SizeChangedHandler;
typedef ITypedEventHandler<CoreWindow*, VisibilityChangedEventArgs*> VisibilityChangedHandler;
typedef ITypedEventHandler<CoreWindow*, AutomationProviderRequestedEventArgs*> AutomationProviderRequestedHandler;
+#if _MSC_VER <=1700
+typedef IDisplayPropertiesEventHandler DisplayInformationHandler;
+#else
+typedef ITypedEventHandler<DisplayInformation*, IInspectable*> DisplayInformationHandler;
+#endif
#ifdef Q_OS_WINPHONE
typedef IEventHandler<BackPressedEventArgs*> BackPressedHandler;
#endif
@@ -424,12 +429,13 @@ QWinRTScreen::QWinRTScreen(ICoreWindow *window)
, m_inputContext(Make<QWinRTInputContext>(m_coreWindow).Detach())
#endif
, m_cursor(new QWinRTCursor(window))
+ , m_devicePixelRatio(1.0)
, m_orientation(Qt::PrimaryOrientation)
, m_touchDevice(Q_NULLPTR)
{
Rect rect;
window->get_Bounds(&rect);
- m_geometry = QRect(0, 0, rect.Width, rect.Height);
+ m_geometry = QRectF(0, 0, rect.Width, rect.Height);
m_surfaceFormat.setAlphaBufferSize(0);
m_surfaceFormat.setRedBufferSize(8);
@@ -478,26 +484,63 @@ QWinRTScreen::QWinRTScreen(ICoreWindow *window)
m_coreWindow->add_AutomationProviderRequested(Callback<AutomationProviderRequestedHandler>(this, &QWinRTScreen::onAutomationProviderRequested).Get(), &m_tokens[QEvent::InputMethodQuery]);
// Orientation handling
- if (SUCCEEDED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Graphics_Display_DisplayProperties).Get(),
- &m_displayProperties))) {
- // Set native orientation
- DisplayOrientations displayOrientation;
- m_displayProperties->get_NativeOrientation(&displayOrientation);
- m_nativeOrientation = static_cast<Qt::ScreenOrientation>(static_cast<int>(qtOrientationsFromNative(displayOrientation)));
-
- // Set initial orientation
- onOrientationChanged(0);
- setOrientationUpdateMask(m_nativeOrientation);
-
- m_displayProperties->add_OrientationChanged(Callback<IDisplayPropertiesEventHandler>(this, &QWinRTScreen::onOrientationChanged).Get(),
- &m_tokens[QEvent::OrientationChange]);
+#if _MSC_VER<=1700
+ HRESULT hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Graphics_Display_DisplayProperties).Get(),
+ &m_displayInformation);
+#else
+ HRESULT hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Graphics_Display_DisplayInformation).Get(),
+ &m_displayInformationFactory);
+ if (FAILED(hr)) {
+ qErrnoWarning(hr, "Failed to get display information factory.");
+ return;
}
-#ifndef Q_OS_WINPHONE
- GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_ViewManagement_ApplicationView).Get(),
- &m_applicationView);
+ hr = m_displayInformationFactory->GetForCurrentView(&m_displayInformation);
+#endif
+
+ if (FAILED(hr)) {
+ qErrnoWarning(hr, "Failed to get display information for the current view.");
+ return;
+ }
+
+ // Set native orientation
+ DisplayOrientations displayOrientation;
+ hr = m_displayInformation->get_NativeOrientation(&displayOrientation);
+ if (FAILED(hr)) {
+ qErrnoWarning(hr, "Failed to get native orientation.");
+ return;
+ }
+
+ m_nativeOrientation = static_cast<Qt::ScreenOrientation>(static_cast<int>(qtOrientationsFromNative(displayOrientation)));
+
+ hr = m_displayInformation->add_OrientationChanged(Callback<DisplayInformationHandler>(this, &QWinRTScreen::onOrientationChanged).Get(),
+ &m_tokens[QEvent::OrientationChange]);
+ if (FAILED(hr)) {
+ qErrnoWarning(hr, "Failed to add orientation change callback.");
+ return;
+ }
+
+#if _MSC_VER<=1700
+ hr = m_displayInformation->add_LogicalDpiChanged(Callback<DisplayInformationHandler>(this, &QWinRTScreen::onDpiChanged).Get(),
+ &m_tokens[QEvent::Type(QEvent::User + 1)]);
+#else
+ hr = m_displayInformation->add_DpiChanged(Callback<DisplayInformationHandler>(this, &QWinRTScreen::onDpiChanged).Get(),
+ &m_tokens[QEvent::Type(QEvent::User + 1)]);
#endif
+ if (FAILED(hr)) {
+ qErrnoWarning(hr, "Failed to add logical dpi change callback.");
+ return;
+ }
+ // Set initial orientation & pixel density
+#if _MSC_VER<=1700
+ onOrientationChanged(Q_NULLPTR);
+ onDpiChanged(Q_NULLPTR);
+#else
+ onOrientationChanged(Q_NULLPTR, Q_NULLPTR);
+ onDpiChanged(Q_NULLPTR, Q_NULLPTR);
+#endif
+ setOrientationUpdateMask(m_nativeOrientation);
if (SUCCEEDED(RoGetActivationFactory(Wrappers::HString::MakeReference(RuntimeClass_Windows_ApplicationModel_Core_CoreApplication).Get(),
IID_PPV_ARGS(&m_application)))) {
@@ -508,7 +551,7 @@ QWinRTScreen::QWinRTScreen(ICoreWindow *window)
QRect QWinRTScreen::geometry() const
{
- return m_geometry;
+ return m_geometry.toRect();
}
int QWinRTScreen::depth() const
@@ -526,6 +569,21 @@ QSurfaceFormat QWinRTScreen::surfaceFormat() const
return m_surfaceFormat;
}
+QSizeF QWinRTScreen::physicalSize() const
+{
+ return m_geometry.size() / m_dpi * qreal(25.4);
+}
+
+QDpi QWinRTScreen::logicalDpi() const
+{
+ return QDpi(m_dpi, m_dpi);
+}
+
+qreal QWinRTScreen::devicePixelRatio() const
+{
+ return m_devicePixelRatio;
+}
+
QWinRTInputContext *QWinRTScreen::inputContext() const
{
return m_inputContext;
@@ -572,7 +630,11 @@ Qt::ScreenOrientation QWinRTScreen::orientation() const
void QWinRTScreen::setOrientationUpdateMask(Qt::ScreenOrientations mask)
{
- m_displayProperties->put_AutoRotationPreferences(nativeOrientationsFromQt(mask));
+#if _MSC_VER<=1700
+ m_displayInformation->put_AutoRotationPreferences(nativeOrientationsFromQt(mask));
+#else
+ m_displayInformationFactory->put_AutoRotationPreferences(nativeOrientationsFromQt(mask));
+#endif
}
ICoreWindow *QWinRTScreen::coreWindow() const
@@ -637,7 +699,7 @@ void QWinRTScreen::handleExpose()
if (m_visibleWindows.isEmpty())
return;
QList<QWindow *>::const_iterator it = m_visibleWindows.constBegin();
- QWindowSystemInterface::handleExposeEvent(*it, m_geometry);
+ QWindowSystemInterface::handleExposeEvent(*it, m_geometry.toRect());
while (++it != m_visibleWindows.constEnd())
QWindowSystemInterface::handleExposeEvent(*it, QRegion());
QWindowSystemInterface::flushWindowSystemEvents();
@@ -898,6 +960,8 @@ HRESULT QWinRTScreen::onAutomationProviderRequested(ICoreWindow *, IAutomationPr
{
#ifndef Q_OS_WINPHONE
args->put_AutomationProvider(m_inputContext);
+#else
+ Q_UNUSED(args)
#endif
return S_OK;
}
@@ -914,9 +978,9 @@ HRESULT QWinRTScreen::onSizeChanged(ICoreWindow *window, IWindowSizeChangedEvent
// Regardless of state, all top-level windows are viewport-sized - this might change if
// a more advanced compositor is written.
- m_geometry.setSize(QSize(size.Width, size.Height));
- QWindowSystemInterface::handleScreenGeometryChange(screen(), m_geometry);
- QWindowSystemInterface::handleScreenAvailableGeometryChange(screen(), m_geometry);
+ m_geometry.setSize(QSizeF(size.Width, size.Height));
+ QWindowSystemInterface::handleScreenGeometryChange(screen(), m_geometry.toRect());
+ QWindowSystemInterface::handleScreenAvailableGeometryChange(screen(), m_geometry.toRect());
QPlatformScreen::resizeMaximizedWindows();
handleExpose();
@@ -981,10 +1045,14 @@ HRESULT QWinRTScreen::onVisibilityChanged(ICoreWindow *window, IVisibilityChange
return S_OK;
}
+#if _MSC_VER<=1700
HRESULT QWinRTScreen::onOrientationChanged(IInspectable *)
+#else
+HRESULT QWinRTScreen::onOrientationChanged(IDisplayInformation *, IInspectable *)
+#endif
{
DisplayOrientations displayOrientation;
- m_displayProperties->get_CurrentOrientation(&displayOrientation);
+ m_displayInformation->get_CurrentOrientation(&displayOrientation);
Qt::ScreenOrientation newOrientation = static_cast<Qt::ScreenOrientation>(static_cast<int>(qtOrientationsFromNative(displayOrientation)));
if (m_orientation != newOrientation) {
m_orientation = newOrientation;
@@ -994,6 +1062,47 @@ HRESULT QWinRTScreen::onOrientationChanged(IInspectable *)
return S_OK;
}
+#if _MSC_VER<=1700
+HRESULT QWinRTScreen::onDpiChanged(IInspectable *)
+#else
+HRESULT QWinRTScreen::onDpiChanged(IDisplayInformation *, IInspectable *)
+#endif
+{
+#if defined(Q_OS_WINPHONE) && _MSC_VER>=1800 // WP 8.1
+ ComPtr<IDisplayInformation2> displayInformation;
+ HRESULT hr = m_displayInformation->QueryInterface(IID_IDisplayInformation2, &displayInformation);
+ if (FAILED(hr)) {
+ qErrnoWarning(hr, "Failed to cast display information.");
+ return S_OK;
+ }
+ hr = displayInformation->get_RawPixelsPerViewPixel(&m_devicePixelRatio);
+#else
+ ResolutionScale resolutionScale;
+ HRESULT hr = m_displayInformation->get_ResolutionScale(&resolutionScale);
+#endif
+ if (FAILED(hr)) {
+ qErrnoWarning(hr, "Failed to get display resolution scale.");
+ return S_OK;
+ }
+#if !(defined(Q_OS_WINPHONE) && _MSC_VER>=1800) // !WP8.1
+ m_devicePixelRatio = qreal(resolutionScale) / 100;
+#endif
+
+ // Correct the scale factor for integer window size
+ m_devicePixelRatio = m_devicePixelRatio * ((m_geometry.width()/qRound(m_geometry.width()) +
+ m_geometry.height()/qRound(m_geometry.height())) / 2.0);
+
+ FLOAT dpi;
+ hr = m_displayInformation->get_LogicalDpi(&dpi);
+ if (FAILED(hr)) {
+ qErrnoWarning(hr, "Failed to get logical DPI.");
+ return S_OK;
+ }
+ m_dpi = dpi;
+
+ return S_OK;
+}
+
#ifdef Q_OS_WINPHONE
HRESULT QWinRTScreen::onBackButtonPressed(IInspectable *, IBackPressedEventArgs *args)
{
diff --git a/src/plugins/platforms/winrt/qwinrtscreen.h b/src/plugins/platforms/winrt/qwinrtscreen.h
index 753d89541c..d39683a960 100644
--- a/src/plugins/platforms/winrt/qwinrtscreen.h
+++ b/src/plugins/platforms/winrt/qwinrtscreen.h
@@ -78,6 +78,8 @@ namespace ABI {
namespace Graphics {
namespace Display {
struct IDisplayPropertiesStatics;
+ struct IDisplayInformationStatics;
+ struct IDisplayInformation;
}
}
#ifdef Q_OS_WINPHONE
@@ -109,6 +111,9 @@ public:
int depth() const;
QImage::Format format() const;
QSurfaceFormat surfaceFormat() const;
+ QSizeF physicalSize() const Q_DECL_OVERRIDE;
+ QDpi logicalDpi() const Q_DECL_OVERRIDE;
+ qreal devicePixelRatio() const Q_DECL_OVERRIDE;
QWinRTInputContext *inputContext() const;
QPlatformCursor *cursor() const;
Qt::KeyboardModifiers keyboardModifiers() const;
@@ -150,7 +155,13 @@ private:
HRESULT onVisibilityChanged(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IVisibilityChangedEventArgs *args);
HRESULT onAutomationProviderRequested(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IAutomationProviderRequestedEventArgs *args);
+#if _MSC_VER<=1700
HRESULT onOrientationChanged(IInspectable *);
+ HRESULT onDpiChanged(IInspectable *);
+#else
+ HRESULT onOrientationChanged(ABI::Windows::Graphics::Display::IDisplayInformation *, IInspectable *);
+ HRESULT onDpiChanged(ABI::Windows::Graphics::Display::IDisplayInformation *, IInspectable *);
+#endif
#ifdef Q_OS_WINPHONE
HRESULT onBackButtonPressed(IInspectable *, ABI::Windows::Phone::UI::Input::IBackPressedEventArgs *args);
@@ -160,9 +171,10 @@ private:
ABI::Windows::UI::ViewManagement::IApplicationViewStatics *m_applicationView;
ABI::Windows::ApplicationModel::Core::ICoreApplication *m_application;
- QRect m_geometry;
+ QRectF m_geometry;
QImage::Format m_format;
QSurfaceFormat m_surfaceFormat;
+ qreal m_dpi;
int m_depth;
QWinRTInputContext *m_inputContext;
QWinRTCursor *m_cursor;
@@ -171,7 +183,13 @@ private:
EGLDisplay m_eglDisplay;
EGLSurface m_eglSurface;
- ABI::Windows::Graphics::Display::IDisplayPropertiesStatics *m_displayProperties;
+#if _MSC_VER<=1700
+ ABI::Windows::Graphics::Display::IDisplayPropertiesStatics *m_displayInformation;
+#else
+ ABI::Windows::Graphics::Display::IDisplayInformationStatics *m_displayInformationFactory;
+ ABI::Windows::Graphics::Display::IDisplayInformation *m_displayInformation;
+#endif
+ qreal m_devicePixelRatio;
Qt::ScreenOrientation m_nativeOrientation;
Qt::ScreenOrientation m_orientation;
diff --git a/src/plugins/platforms/winrt/qwinrtservices.cpp b/src/plugins/platforms/winrt/qwinrtservices.cpp
index 73c090351b..b0f9247d36 100644
--- a/src/plugins/platforms/winrt/qwinrtservices.cpp
+++ b/src/plugins/platforms/winrt/qwinrtservices.cpp
@@ -81,9 +81,11 @@ bool QWinRTServices::openUrl(const QUrl &url)
return QPlatformServices::openUrl(url);
IUriRuntimeClass *uri;
- QString urlString = url.toString(); HSTRING uriString; HSTRING_HEADER header;
- WindowsCreateStringReference((const wchar_t*)urlString.utf16(), urlString.length(), &header, &uriString);
- m_uriFactory->CreateUri(uriString, &uri);
+ QString urlString = url.toString();
+ // ### TODO: Replace with HStringReference when WP8.0 support is removed
+ HString uriString;
+ uriString.Set((const wchar_t*)urlString.utf16(), urlString.length());
+ m_uriFactory->CreateUri(uriString.Get(), &uri);
if (!uri)
return false;
@@ -107,10 +109,11 @@ bool QWinRTServices::openDocument(const QUrl &url)
return QPlatformServices::openDocument(url);
const QString pathString = QDir::toNativeSeparators(url.toLocalFile());
- HSTRING_HEADER header; HSTRING path;
- WindowsCreateStringReference((const wchar_t*)pathString.utf16(), pathString.length(), &header, &path);
+ // ### TODO: Replace with HStringReference when WP8.0 support is removed
+ HString path;
+ path.Set((const wchar_t*)pathString.utf16(), pathString.length());
IAsyncOperation<StorageFile*> *fileOp;
- m_fileFactory->GetFileFromPathAsync(path, &fileOp);
+ m_fileFactory->GetFileFromPathAsync(path.Get(), &fileOp);
if (!fileOp)
return false;
diff --git a/src/plugins/platforms/winrt/qwinrtwindow.cpp b/src/plugins/platforms/winrt/qwinrtwindow.cpp
index 88b753b463..80ee6bd761 100644
--- a/src/plugins/platforms/winrt/qwinrtwindow.cpp
+++ b/src/plugins/platforms/winrt/qwinrtwindow.cpp
@@ -116,4 +116,9 @@ void QWinRTWindow::lower()
m_screen->lower(window());
}
+qreal QWinRTWindow::devicePixelRatio() const
+{
+ return screen()->devicePixelRatio();
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtwindow.h b/src/plugins/platforms/winrt/qwinrtwindow.h
index 1f19b4f2d5..121f430686 100644
--- a/src/plugins/platforms/winrt/qwinrtwindow.h
+++ b/src/plugins/platforms/winrt/qwinrtwindow.h
@@ -63,6 +63,8 @@ public:
void raise();
void lower();
+ qreal devicePixelRatio() const Q_DECL_OVERRIDE;
+
private:
QWinRTScreen *m_screen;
};
diff --git a/src/plugins/platforms/winrt/winrt.pro b/src/plugins/platforms/winrt/winrt.pro
index 0122bf9475..349cdf11c9 100644
--- a/src/plugins/platforms/winrt/winrt.pro
+++ b/src/plugins/platforms/winrt/winrt.pro
@@ -3,8 +3,7 @@ CONFIG -= precompile_header
# For Windows Phone 8 we have to deploy fonts together with the application as DirectWrite
# is not supported here.
-# TODO: Add a condition/remove this block if Windows Phone 8.1 supports DirectWrite
-winphone {
+winphone:equals(WINSDK_VER, 8.0): {
fonts.path = $$[QT_INSTALL_LIBS]/fonts
fonts.files = $$QT_SOURCE_TREE/lib/fonts/DejaVu*.ttf
INSTALLS += fonts
@@ -21,9 +20,10 @@ DEFINES *= QT_NO_CAST_FROM_ASCII __WRL_NO_DEFAULT_LIB__ GL_GLEXT_PROTOTYPES
LIBS += $$QMAKE_LIBS_CORE
-!winphone {
+!if(winphone:equals(WINSDK_VER, 8.0)) {
LIBS += -ldwrite
INCLUDEPATH += $$QT_SOURCE_TREE/src/3rdparty/freetype/include
+ DEFINES += QT_WINRT_USE_DWRITE
}
SOURCES = \
@@ -70,7 +70,7 @@ fxc_blitvs.variable_out = HEADERS
fxc_blitvs.CONFIG += target_predeps
QMAKE_EXTRA_COMPILERS += fxc_blitps fxc_blitvs
-winphone {
+winphone:equals(WINSDK_VER, 8.0): {
SOURCES -= qwinrtplatformmessagedialoghelper.cpp
HEADERS -= qwinrtplatformmessagedialoghelper.h
}
diff --git a/src/plugins/platforms/xcb/qglxintegration.cpp b/src/plugins/platforms/xcb/qglxintegration.cpp
index c18764a4bb..df929c4b61 100644
--- a/src/plugins/platforms/xcb/qglxintegration.cpp
+++ b/src/plugins/platforms/xcb/qglxintegration.cpp
@@ -516,6 +516,15 @@ void QGLXContext::swapBuffers(QPlatformSurface *surface)
else
glxDrawable = static_cast<QXcbWindow *>(surface)->xcb_window();
glXSwapBuffers(DISPLAY_FROM_XCB(m_screen), glxDrawable);
+
+ if (surface->surface()->surfaceClass() == QSurface::Window) {
+ QXcbWindow *platformWindow = static_cast<QXcbWindow *>(surface);
+ // OpenGL context might be bound to a non-gui thread
+ // use QueuedConnection to sync the window from the platformWindow's thread
+ // as QXcbWindow is no QObject, a wrapper slot in QXcbConnection is used.
+ if (platformWindow->needsSync())
+ QMetaObject::invokeMethod(m_screen->connection(), "syncWindow", Qt::QueuedConnection, Q_ARG(QXcbWindow*, platformWindow));
+ }
}
void (*QGLXContext::getProcAddress(const QByteArray &procName)) ()
diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp
index 57d6bc580b..ada5b0eedf 100644
--- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp
+++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp
@@ -261,7 +261,6 @@ void QXcbShmImage::preparePaint(const QRegion &region)
QXcbBackingStore::QXcbBackingStore(QWindow *window)
: QPlatformBackingStore(window)
, m_image(0)
- , m_syncingResize(false)
{
QXcbScreen *screen = static_cast<QXcbScreen *>(window->screen()->handle());
setConnection(screen->connection());
@@ -330,13 +329,10 @@ void QXcbBackingStore::flush(QWindow *window, const QRegion &region, const QPoin
Q_XCB_NOOP(connection());
- if (m_syncingResize) {
- connection()->sync();
- m_syncingResize = false;
+ if (platformWindow->needsSync())
platformWindow->updateSyncRequestCounter();
- } else {
+ else
xcb_flush(xcb_connection());
- }
}
#ifndef QT_NO_OPENGL
@@ -347,10 +343,8 @@ void QXcbBackingStore::composeAndFlush(QWindow *window, const QRegion &region, c
Q_XCB_NOOP(connection());
- if (m_syncingResize) {
- QXcbWindow *platformWindow = static_cast<QXcbWindow *>(window->handle());
- connection()->sync();
- m_syncingResize = false;
+ QXcbWindow *platformWindow = static_cast<QXcbWindow *>(window->handle());
+ if (platformWindow->needsSync()) {
platformWindow->updateSyncRequestCounter();
} else {
xcb_flush(xcb_connection());
@@ -376,8 +370,6 @@ void QXcbBackingStore::resize(const QSize &size, const QRegion &)
delete m_image;
m_image = new QXcbShmImage(screen, size, win->depth(), win->imageFormat());
Q_XCB_NOOP(connection());
-
- m_syncingResize = true;
}
extern void qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset);
diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.h b/src/plugins/platforms/xcb/qxcbbackingstore.h
index 19a5ac62d0..af3c004c2d 100644
--- a/src/plugins/platforms/xcb/qxcbbackingstore.h
+++ b/src/plugins/platforms/xcb/qxcbbackingstore.h
@@ -72,7 +72,6 @@ public:
private:
QXcbShmImage *m_image;
- bool m_syncingResize;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index f5f6c712c5..1b72bb0da1 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -1833,6 +1833,11 @@ QXcbSystemTrayTracker *QXcbConnection::systemTrayTracker()
return m_systemTrayTracker;
}
+void QXcbConnection::syncWindow(QXcbWindow *window)
+{
+ window->updateSyncRequestCounter();
+}
+
QXcbConnectionGrabber::QXcbConnectionGrabber(QXcbConnection *connection)
:m_connection(connection)
{
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
index 1af9f1fdd1..12143a7e4b 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.h
+++ b/src/plugins/platforms/xcb/qxcbconnection.h
@@ -465,6 +465,9 @@ public:
void handleEnterEvent(const xcb_enter_notify_event_t *);
#endif
+public slots:
+ void syncWindow(QXcbWindow *window);
+
private slots:
void processXcbEvents();
diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp
index 0315d0762f..36a4b5c5db 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.cpp
+++ b/src/plugins/platforms/xcb/qxcbintegration.cpp
@@ -128,6 +128,7 @@ QXcbIntegration::QXcbIntegration(const QStringList &parameters, int &argc, char
: m_services(new QGenericUnixServices)
, m_instanceName(0)
{
+ qRegisterMetaType<QXcbWindow*>();
#ifdef XCB_USE_XLIB
XInitThreads();
#endif
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index e4ffda21ea..4b9a99486f 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -202,6 +202,7 @@ QXcbWindow::QXcbWindow(QWindow *window)
, m_eglSurface(0)
#endif
, m_lastWindowStateEvent(-1)
+ , m_syncState(NoSyncNeeded)
{
m_screen = static_cast<QXcbScreen *>(window->screen()->handle());
@@ -369,7 +370,12 @@ void QXcbWindow::create()
properties[propertyCount++] = atom(QXcbAtom::WM_TAKE_FOCUS);
properties[propertyCount++] = atom(QXcbAtom::_NET_WM_PING);
- m_usingSyncProtocol = m_screen->syncRequestSupported() && window()->surfaceType() != QSurface::OpenGLSurface;
+ m_usingSyncProtocol = m_screen->syncRequestSupported();
+#if !defined(XCB_USE_GLX)
+ // synced resize only implemented on GLX
+ if (window()->supportsOpenGL())
+ m_usingSyncProtocol = false;
+#endif
if (m_usingSyncProtocol)
properties[propertyCount++] = atom(QXcbAtom::_NET_WM_SYNC_REQUEST);
@@ -1728,6 +1734,8 @@ void QXcbWindow::handleClientMessageEvent(const xcb_client_message_event_t *even
connection()->setTime(event->data.data32[1]);
m_syncValue.lo = event->data.data32[2];
m_syncValue.hi = event->data.data32[3];
+ if (m_usingSyncProtocol)
+ m_syncState = SyncReceived;
#ifndef QT_NO_WHATSTHIS
} else if (event->data.data32[0] == atom(QXcbAtom::_NET_WM_CONTEXT_HELP)) {
QWindowSystemInterface::handleEnterWhatsThisEvent();
@@ -1801,6 +1809,9 @@ void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t *
QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size()));
}
+ if (m_usingSyncProtocol && m_syncState == SyncReceived)
+ m_syncState = SyncAndConfigureReceived;
+
m_dirtyFrameMargins = true;
}
@@ -2077,12 +2088,17 @@ void QXcbWindow::handleFocusOutEvent(const xcb_focus_out_event_t *)
void QXcbWindow::updateSyncRequestCounter()
{
+ if (m_syncState != SyncAndConfigureReceived) {
+ // window manager does not expect a sync event yet.
+ return;
+ }
if (m_usingSyncProtocol && (m_syncValue.lo != 0 || m_syncValue.hi != 0)) {
Q_XCB_CALL(xcb_sync_set_counter(xcb_connection(), m_syncCounter, m_syncValue));
- connection()->sync();
+ xcb_flush(xcb_connection());
m_syncValue.lo = 0;
m_syncValue.hi = 0;
+ m_syncState = NoSyncNeeded;
}
}
@@ -2305,4 +2321,9 @@ void QXcbWindow::setAlertState(bool enabled)
}
}
+bool QXcbWindow::needsSync() const
+{
+ return m_syncState == SyncAndConfigureReceived;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h
index 268a2aeaa5..72b5c7bcc9 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.h
+++ b/src/plugins/platforms/xcb/qxcbwindow.h
@@ -146,7 +146,6 @@ public:
void handleMouseEvent(xcb_timestamp_t time, const QPoint &local, const QPoint &global, Qt::KeyboardModifiers modifiers);
- void updateSyncRequestCounter();
void updateNetWmUserTime(xcb_timestamp_t timestamp);
#if defined(XCB_USE_EGL)
@@ -158,6 +157,11 @@ public:
QXcbWindowFunctions::WmWindowTypes wmWindowTypes() const;
void setWmWindowType(QXcbWindowFunctions::WmWindowTypes types);
+ bool needsSync() const;
+
+public Q_SLOTS:
+ void updateSyncRequestCounter();
+
private:
void changeNetWmState(bool set, xcb_atom_t one, xcb_atom_t two = 0);
NetWmStates netWmStates();
@@ -224,8 +228,17 @@ private:
xcb_visualid_t m_visualId;
int m_lastWindowStateEvent;
+
+ enum SyncState {
+ NoSyncNeeded,
+ SyncReceived,
+ SyncAndConfigureReceived
+ };
+ SyncState m_syncState;
};
QT_END_NAMESPACE
+Q_DECLARE_METATYPE(QXcbWindow*)
+
#endif