summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/windows
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/windows')
-rw-r--r--src/plugins/platforms/windows/accessible/accessible.pri17
-rw-r--r--src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp36
-rw-r--r--src/plugins/platforms/windows/openglblacklists/default.json65
-rw-r--r--src/plugins/platforms/windows/qwindowsbackingstore.cpp66
-rw-r--r--src/plugins/platforms/windows/qwindowsbackingstore.h9
-rw-r--r--src/plugins/platforms/windows/qwindowsclipboard.cpp12
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp70
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.h9
-rw-r--r--src/plugins/platforms/windows/qwindowscursor.cpp330
-rw-r--r--src/plugins/platforms/windows/qwindowscursor.h77
-rw-r--r--src/plugins/platforms/windows/qwindowsdialoghelpers.cpp54
-rw-r--r--src/plugins/platforms/windows/qwindowsdrag.cpp163
-rw-r--r--src/plugins/platforms/windows/qwindowsdrag.h10
-rw-r--r--src/plugins/platforms/windows/qwindowseglcontext.cpp62
-rw-r--r--src/plugins/platforms/windows/qwindowsfontdatabase.cpp69
-rw-r--r--src/plugins/platforms/windows/qwindowsfontdatabase.h4
-rw-r--r--src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp77
-rw-r--r--src/plugins/platforms/windows/qwindowsfontdatabase_ft.h11
-rw-r--r--src/plugins/platforms/windows/qwindowsfontengine.cpp15
-rw-r--r--src/plugins/platforms/windows/qwindowsfontengine.h2
-rw-r--r--src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp44
-rw-r--r--src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h41
-rw-r--r--src/plugins/platforms/windows/qwindowsglcontext.cpp69
-rw-r--r--src/plugins/platforms/windows/qwindowsglcontext.h6
-rw-r--r--src/plugins/platforms/windows/qwindowsguieventdispatcher.cpp201
-rw-r--r--src/plugins/platforms/windows/qwindowsguieventdispatcher.h60
-rw-r--r--src/plugins/platforms/windows/qwindowsinputcontext.cpp80
-rw-r--r--src/plugins/platforms/windows/qwindowsinputcontext.h11
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.cpp73
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.h12
-rw-r--r--src/plugins/platforms/windows/qwindowskeymapper.cpp26
-rw-r--r--src/plugins/platforms/windows/qwindowsmime.cpp159
-rw-r--r--src/plugins/platforms/windows/qwindowsmime.h8
-rw-r--r--src/plugins/platforms/windows/qwindowsmousehandler.cpp43
-rw-r--r--src/plugins/platforms/windows/qwindowsnativeimage.h2
-rw-r--r--src/plugins/platforms/windows/qwindowsnativeinterface.cpp2
-rw-r--r--src/plugins/platforms/windows/qwindowsole.cpp17
-rw-r--r--src/plugins/platforms/windows/qwindowsopengltester.cpp17
-rw-r--r--src/plugins/platforms/windows/qwindowsopengltester.h8
-rw-r--r--src/plugins/platforms/windows/qwindowsscaling.cpp71
-rw-r--r--src/plugins/platforms/windows/qwindowsscaling.h106
-rw-r--r--src/plugins/platforms/windows/qwindowsscreen.cpp132
-rw-r--r--src/plugins/platforms/windows/qwindowsscreen.h23
-rw-r--r--src/plugins/platforms/windows/qwindowstabletsupport.cpp30
-rw-r--r--src/plugins/platforms/windows/qwindowstabletsupport.h2
-rw-r--r--src/plugins/platforms/windows/qwindowstheme.cpp13
-rw-r--r--src/plugins/platforms/windows/qwindowstheme.h4
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp239
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.h67
-rw-r--r--src/plugins/platforms/windows/windows.pri8
50 files changed, 1394 insertions, 1338 deletions
diff --git a/src/plugins/platforms/windows/accessible/accessible.pri b/src/plugins/platforms/windows/accessible/accessible.pri
index e26c6614e2..0774d907f2 100644
--- a/src/plugins/platforms/windows/accessible/accessible.pri
+++ b/src/plugins/platforms/windows/accessible/accessible.pri
@@ -1,17 +1,20 @@
SOURCES += \
- $$PWD/qwindowsmsaaaccessible.cpp \
$$PWD/qwindowsaccessibility.cpp \
$$PWD/comutils.cpp
HEADERS += \
- $$PWD/qwindowsmsaaaccessible.h \
$$PWD/qwindowsaccessibility.h \
$$PWD/comutils.h
-!mingw: {
- SOURCES += $$PWD/iaccessible2.cpp
- HEADERS += $$PWD/iaccessible2.h
- include(../../../../3rdparty/iaccessible2/iaccessible2.pri)
+!wince: {
+ SOURCES += $$PWD/qwindowsmsaaaccessible.cpp
+ HEADERS += $$PWD/qwindowsmsaaaccessible.h
+
+ !mingw: {
+ SOURCES += $$PWD/iaccessible2.cpp
+ HEADERS += $$PWD/iaccessible2.h
+ include(../../../../3rdparty/iaccessible2/iaccessible2.pri)
+ }
}
-mingw: LIBS *= -luuid \ No newline at end of file
+mingw: LIBS *= -luuid
diff --git a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp
index 0bf3c27350..0437290dcb 100644
--- a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp
+++ b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp
@@ -50,10 +50,12 @@
#include <QtGui/qguiapplication.h>
#include "qwindowsaccessibility.h"
-#ifdef Q_CC_MINGW
-# include "qwindowsmsaaaccessible.h"
-#else
-# include "iaccessible2.h"
+#if !defined(Q_OS_WINCE)
+# ifdef Q_CC_MINGW
+# include "qwindowsmsaaaccessible.h"
+# else
+# include "iaccessible2.h"
+# endif
#endif
#include "comutils.h"
@@ -68,8 +70,9 @@
#if !defined(WINABLEAPI)
# if defined(Q_OS_WINCE)
# include <bldver.h>
+# else
+# include <winable.h>
# endif
-# include <winable.h>
#endif
#include <servprov.h>
@@ -151,7 +154,7 @@ void QWindowsAccessibility::notifyAccessibilityUpdate(QAccessibleEvent *event)
// An event has to be associated with a window,
// so find the first parent that is a widget and that has a WId
QAccessibleInterface *iface = event->accessibleInterface();
- if (!iface || !iface->isValid())
+ if (!isActive() || !iface || !iface->isValid())
return;
QWindow *window = QWindowsAccessibility::windowHelper(iface);
@@ -193,6 +196,11 @@ QWindow *QWindowsAccessibility::windowHelper(const QAccessibleInterface *iface)
*/
IAccessible *QWindowsAccessibility::wrap(QAccessibleInterface *acc)
{
+#if defined(Q_OS_WINCE)
+ Q_UNUSED(acc);
+
+ return 0;
+#else
if (!acc)
return 0;
@@ -200,14 +208,15 @@ IAccessible *QWindowsAccessibility::wrap(QAccessibleInterface *acc)
if (!QAccessible::uniqueId(acc))
QAccessible::registerAccessibleInterface(acc);
-#ifdef Q_CC_MINGW
+# ifdef Q_CC_MINGW
QWindowsMsaaAccessible *wacc = new QWindowsMsaaAccessible(acc);
-#else
+# else
QWindowsIA2Accessible *wacc = new QWindowsIA2Accessible(acc);
-#endif
+# endif
IAccessible *iacc = 0;
wacc->QueryInterface(IID_IAccessible, (void**)&iacc);
return iacc;
+#endif // defined(Q_OS_WINCE)
}
/*
@@ -230,6 +239,7 @@ void QWindowsAccessibility::cleanup()
bool QWindowsAccessibility::handleAccessibleObjectFromWindowRequest(HWND hwnd, WPARAM wParam, LPARAM lParam, LRESULT *lResult)
{
+#if !defined(Q_OS_WINCE)
if (static_cast<long>(lParam) == static_cast<long>(UiaRootObjectId)) {
/* For UI Automation */
} else if ((DWORD)lParam == DWORD(OBJID_CLIENT)) {
@@ -248,9 +258,7 @@ bool QWindowsAccessibility::handleAccessibleObjectFromWindowRequest(HWND hwnd, W
if (!oleaccChecked) {
oleaccChecked = true;
-#if !defined(Q_OS_WINCE)
ptrLresultFromObject = (PtrLresultFromObject)QSystemLibrary::resolve(QLatin1String("oleacc"), "LresultFromObject");
-#endif
}
if (ptrLresultFromObject) {
@@ -269,6 +277,12 @@ bool QWindowsAccessibility::handleAccessibleObjectFromWindowRequest(HWND hwnd, W
}
}
}
+#else
+ Q_UNUSED(hwnd);
+ Q_UNUSED(wParam);
+ Q_UNUSED(lParam);
+ Q_UNUSED(lResult);
+#endif // !defined(Q_OS_WINCE)
return false;
}
diff --git a/src/plugins/platforms/windows/openglblacklists/default.json b/src/plugins/platforms/windows/openglblacklists/default.json
index 23607523bd..767eac161c 100644
--- a/src/plugins/platforms/windows/openglblacklists/default.json
+++ b/src/plugins/platforms/windows/openglblacklists/default.json
@@ -1,10 +1,10 @@
{
"name": "Qt built-in GPU driver blacklist",
- "version": "5.5",
+ "version": "5.6",
"entries": [
{
"id": 1,
- "description": "Desktop OpenGL is unreliable on some Intel HD laptops (QTBUG-43263, QTBUG-42240)",
+ "description": "Desktop OpenGL is unreliable on some Intel HD laptops (QTBUG-43263)",
"vendor_id": "0x8086",
"device_id": [ "0x0A16" ],
"os": {
@@ -17,6 +17,67 @@
"features": [
"disable_desktopgl"
]
+ },
+ {
+ "id": 2,
+ "description": "Intel Q965/Q963 - GMA 3000 has insufficient support of opengl and directx",
+ "vendor_id": "0x8086",
+ "device_id": [ "0x2992" ],
+ "os": {
+ "type": "win"
+ },
+ "features": [
+ "disable_desktopgl",
+ "disable_angle"
+ ]
+ },
+ {
+ "id": 3,
+ "description": "No OpenGL on Intel G33/G31 (QTBUG-47522)",
+ "vendor_id": "0x8086",
+ "device_id": [ "0x29C2" ],
+ "os": {
+ "type": "win"
+ },
+ "features": [
+ "disable_desktopgl"
+ ]
+ },
+ {
+ "id": 4,
+ "description": "Intel HD Graphics 3000 crashes when initializing the OpenGL driver (QTBUG-42240)",
+ "vendor_id": "0x8086",
+ "device_id": [ "0x0102", "0x0106", "0x010A", "0x0112", "0x0116", "0x0122", "0x0126" ],
+ "os": {
+ "type": "win"
+ },
+ "features": [
+ "disable_desktopgl"
+ ]
+ },
+ {
+ "id": 5,
+ "description": "Intel GMA 3150 (QTBUG-43243), Mobile Intel 945GM (QTBUG-47435) crash",
+ "vendor_id": "0x8086",
+ "device_id": [ "0xA001", "0xA011", "0x27A0" ],
+ "os": {
+ "type": "win"
+ },
+ "features": [
+ "disable_desktopgl", "disable_angle"
+ ]
+ },
+ {
+ "id": 6,
+ "description": "Intel(R) HD Graphics 4000 / 5500 cause crashes on orientation changes in fullscreen mode (QTBUG-49541)",
+ "vendor_id": "0x8086",
+ "device_id": [ "0x0166", "0x1616" ],
+ "os": {
+ "type": "win"
+ },
+ "features": [
+ "disable_rotation"
+ ]
}
]
}
diff --git a/src/plugins/platforms/windows/qwindowsbackingstore.cpp b/src/plugins/platforms/windows/qwindowsbackingstore.cpp
index 16c278d9df..a6b1d0af26 100644
--- a/src/plugins/platforms/windows/qwindowsbackingstore.cpp
+++ b/src/plugins/platforms/windows/qwindowsbackingstore.cpp
@@ -35,10 +35,11 @@
#include "qwindowswindow.h"
#include "qwindowsnativeimage.h"
#include "qwindowscontext.h"
-#include "qwindowsscaling.h"
#include <QtGui/QWindow>
#include <QtGui/QPainter>
+#include <private/qhighdpiscaling_p.h>
+#include <private/qimage_p.h>
#include <QtCore/QDebug>
@@ -52,7 +53,8 @@ QT_BEGIN_NAMESPACE
*/
QWindowsBackingStore::QWindowsBackingStore(QWindow *window) :
- QPlatformBackingStore(window)
+ QPlatformBackingStore(window),
+ m_alphaNeedsFill(false)
{
qCDebug(lcQpaBackingStore) << __FUNCTION__ << this << window;
}
@@ -68,10 +70,12 @@ QPaintDevice *QWindowsBackingStore::paintDevice()
return &m_image->image();
}
-void QWindowsBackingStore::flushDp(QWindow *window, const QRect &br, const QPoint &offset)
+void QWindowsBackingStore::flush(QWindow *window, const QRegion &region,
+ const QPoint &offset)
{
Q_ASSERT(window);
+ const QRect br = region.boundingRect();
if (QWindowsContext::verbose > 1)
qCDebug(lcQpaBackingStore) << __FUNCTION__ << this << window << offset << br;
QWindowsWindow *rw = QWindowsWindow::baseWindowOf(window);
@@ -81,9 +85,9 @@ void QWindowsBackingStore::flushDp(QWindow *window, const QRect &br, const QPoin
const Qt::WindowFlags flags = window->flags();
if ((flags & Qt::FramelessWindowHint) && QWindowsWindow::setWindowLayered(rw->handle(), flags, hasAlpha, rw->opacity()) && hasAlpha) {
// Windows with alpha: Use blend function to update.
- const QMargins marginsDP = rw->frameMarginsDp();
- const QRect r = rw->geometryDp() + marginsDP;
- const QPoint frameOffset(marginsDP.left(), marginsDP.top());
+ QRect r = QHighDpi::toNativePixels(window->frameGeometry(), window);
+ QPoint frameOffset(QHighDpi::toNativePixels(QPoint(window->frameMargins().left(), window->frameMargins().top()),
+ static_cast<const QWindow *>(Q_NULLPTR)));
QRect dirtyRect = br.translated(offset + frameOffset);
SIZE size = {r.width(), r.height()};
@@ -94,7 +98,12 @@ void QWindowsBackingStore::flushDp(QWindow *window, const QRect &br, const QPoin
RECT dirty = {dirtyRect.x(), dirtyRect.y(),
dirtyRect.x() + dirtyRect.width(), dirtyRect.y() + dirtyRect.height()};
UPDATELAYEREDWINDOWINFO info = {sizeof(info), NULL, &ptDst, &size, m_image->hdc(), &ptSrc, 0, &blend, ULW_ALPHA, &dirty};
- QWindowsContext::user32dll.updateLayeredWindowIndirect(rw->handle(), &info);
+ const BOOL result = QWindowsContext::user32dll.updateLayeredWindowIndirect(rw->handle(), &info);
+ if (!result)
+ qErrnoWarning("UpdateLayeredWindowIndirect failed for ptDst=(%d, %d),"
+ " size=(%dx%d), dirty=(%dx%d %d, %d)", r.x(), r.y(),
+ r.width(), r.height(), dirtyRect.width(), dirtyRect.height(),
+ dirtyRect.x(), dirtyRect.y());
} else {
QWindowsContext::user32dll.updateLayeredWindow(rw->handle(), NULL, &ptDst, &size, m_image->hdc(), &ptSrc, 0, &blend, ULW_ALPHA);
}
@@ -127,27 +136,34 @@ void QWindowsBackingStore::flushDp(QWindow *window, const QRect &br, const QPoin
}
}
-void QWindowsBackingStore::resize(const QSize &sizeDip, const QRegion &regionDip)
+void QWindowsBackingStore::resize(const QSize &size, const QRegion &region)
{
- const QSize size = sizeDip * QWindowsScaling::factor();
if (m_image.isNull() || m_image->image().size() != size) {
#ifndef QT_NO_DEBUG_OUTPUT
if (QWindowsContext::verbose && lcQpaBackingStore().isDebugEnabled()) {
qCDebug(lcQpaBackingStore)
- << __FUNCTION__ << ' ' << window() << ' ' << size << ' ' << sizeDip << ' '
- << regionDip << " from: " << (m_image.isNull() ? QSize() : m_image->image().size());
+ << __FUNCTION__ << ' ' << window() << ' ' << size << ' ' << region
+ << " from: " << (m_image.isNull() ? QSize() : m_image->image().size());
}
#endif
- const QImage::Format format = window()->format().hasAlpha() ?
- QImage::Format_ARGB32_Premultiplied : QWindowsNativeImage::systemFormat();
+ QImage::Format format = window()->format().hasAlpha() ?
+ QImage::Format_ARGB32_Premultiplied : QWindowsNativeImage::systemFormat();
+
+ // The backingstore composition (enabling render-to-texture widgets)
+ // punches holes in the backingstores using the alpha channel. Hence
+ // the need for a true alpha format.
+ if (QImage::toPixelFormat(format).alphaUsage() == QPixelFormat::UsesAlpha)
+ m_alphaNeedsFill = true;
+ else // upgrade but here we know app painting does not rely on alpha hence no need to fill
+ format = qt_alphaVersionForPainting(format);
QWindowsNativeImage *oldwni = m_image.data();
QWindowsNativeImage *newwni = new QWindowsNativeImage(size.width(), size.height(), format);
- if (oldwni && !regionDip.isEmpty()) {
+ if (oldwni && !region.isEmpty()) {
const QImage &oldimg(oldwni->image());
QImage &newimg(newwni->image());
- QRegion staticRegion = QWindowsScaling::mapToNative(regionDip);
+ QRegion staticRegion(region);
staticRegion &= QRect(0, 0, oldimg.width(), oldimg.height());
staticRegion &= QRect(0, 0, newimg.width(), newimg.height());
QPainter painter(&newimg);
@@ -156,38 +172,36 @@ void QWindowsBackingStore::resize(const QSize &sizeDip, const QRegion &regionDip
painter.drawImage(rect, oldimg, rect);
}
- if (QWindowsScaling::isActive())
- newwni->setDevicePixelRatio(QWindowsScaling::factor());
m_image.reset(newwni);
}
}
Q_GUI_EXPORT void qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset);
-bool QWindowsBackingStore::scroll(const QRegion &areaDip, int dxDip, int dyDip)
+bool QWindowsBackingStore::scroll(const QRegion &area, int dx, int dy)
{
if (m_image.isNull() || m_image->image().isNull())
return false;
- const QPoint dp = QPoint(dxDip, dyDip) * QWindowsScaling::factor();
- const QVector<QRect> rects = areaDip.rects();
+ const QVector<QRect> rects = area.rects();
+ const QPoint offset(dx, dy);
for (int i = 0; i < rects.size(); ++i)
- qt_scrollRectInImage(m_image->image(), QWindowsScaling::mapToNative(rects.at(i)), dp);
+ qt_scrollRectInImage(m_image->image(), rects.at(i), offset);
return true;
}
-void QWindowsBackingStore::beginPaint(const QRegion &regionDip)
+void QWindowsBackingStore::beginPaint(const QRegion &region)
{
if (QWindowsContext::verbose > 1)
- qCDebug(lcQpaBackingStore) <<__FUNCTION__ << regionDip;
+ qCDebug(lcQpaBackingStore) <<__FUNCTION__ << region;
- if (m_image->image().hasAlphaChannel()) {
+ if (m_alphaNeedsFill) {
QPainter p(&m_image->image());
p.setCompositionMode(QPainter::CompositionMode_Source);
const QColor blank = Qt::transparent;
- foreach (const QRect &r, regionDip.rects())
- p.fillRect(QWindowsScaling::mapToNative(r), blank);
+ foreach (const QRect &r, region.rects())
+ p.fillRect(r, blank);
}
}
diff --git a/src/plugins/platforms/windows/qwindowsbackingstore.h b/src/plugins/platforms/windows/qwindowsbackingstore.h
index 41ad29babc..1d644923bb 100644
--- a/src/plugins/platforms/windows/qwindowsbackingstore.h
+++ b/src/plugins/platforms/windows/qwindowsbackingstore.h
@@ -35,7 +35,6 @@
#define QWINDOWSBACKINGSTORE_H
#include "qtwindows_additional.h"
-#include "qwindowsscaling.h"
#include <qpa/qplatformbackingstore.h>
#include <QtCore/QScopedPointer>
@@ -53,12 +52,7 @@ public:
~QWindowsBackingStore();
QPaintDevice *paintDevice() Q_DECL_OVERRIDE;
- void flush(QWindow *window, const QRegion &region, const QPoint &offset) Q_DECL_OVERRIDE
- {
- flushDp(window, QWindowsScaling::mapToNative(region.boundingRect()),
- offset * QWindowsScaling::factor());
- }
- void flushDp(QWindow *window, const QRect &boundingRect, const QPoint &offset);
+ void flush(QWindow *window, const QRegion &region, const QPoint &offset) Q_DECL_OVERRIDE;
void resize(const QSize &size, const QRegion &r) Q_DECL_OVERRIDE;
bool scroll(const QRegion &area, int dx, int dy) Q_DECL_OVERRIDE;
void beginPaint(const QRegion &) Q_DECL_OVERRIDE;
@@ -71,6 +65,7 @@ public:
private:
QScopedPointer<QWindowsNativeImage> m_image;
+ bool m_alphaNeedsFill;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsclipboard.cpp b/src/plugins/platforms/windows/qwindowsclipboard.cpp
index 925427ac30..1071a2e038 100644
--- a/src/plugins/platforms/windows/qwindowsclipboard.cpp
+++ b/src/plugins/platforms/windows/qwindowsclipboard.cpp
@@ -35,7 +35,6 @@
#include "qwindowscontext.h"
#include "qwindowsole.h"
#include "qwindowsmime.h"
-#include "qwindowsguieventdispatcher.h"
#include <QtGui/QGuiApplication>
#include <QtGui/QClipboard>
@@ -48,6 +47,8 @@
#include <QtCore/QVariant>
#include <QtCore/QUrl>
+#include <QtPlatformSupport/private/qwindowsguieventdispatcher_p.h>
+
QT_BEGIN_NAMESPACE
static const char formatTextPlainC[] = "text/plain";
@@ -69,6 +70,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 +95,7 @@ static QDebug operator<<(QDebug d, const QMimeData *mimeData)
d << ')';
return d;
}
+#endif // !QT_NO_DEBUG_STREAM
/*!
\class QWindowsClipboardRetrievalMimeData
@@ -109,8 +112,11 @@ static QDebug operator<<(QDebug d, const QMimeData *mimeData)
IDataObject *QWindowsClipboardRetrievalMimeData::retrieveDataObject() const
{
IDataObject * pDataObj = 0;
- if (OleGetClipboard(&pDataObj) == S_OK)
+ if (OleGetClipboard(&pDataObj) == S_OK) {
+ if (QWindowsContext::verbose > 1)
+ qCDebug(lcQpaMime) << __FUNCTION__ << pDataObj;
return pDataObj;
+ }
return 0;
}
@@ -230,7 +236,7 @@ void QWindowsClipboard::propagateClipboardMessage(UINT message, WPARAM wParam, L
// suspended by a shell prompt 'Select' or debugger).
if (QWindowsContext::user32dll.isHungAppWindow
&& QWindowsContext::user32dll.isHungAppWindow(m_nextClipboardViewer)) {
- qWarning("%s: Cowardly refusing to send clipboard message to hung application...", Q_FUNC_INFO);
+ qWarning("Cowardly refusing to send clipboard message to hung application...");
return;
}
// Do not block if the process is being debugged, specifically, if it is
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index 00049bd0d6..4934b6c6e4 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -36,7 +36,6 @@
#include "qwindowsintegration.h"
#include "qwindowswindow.h"
#include "qwindowskeymapper.h"
-#include "qwindowsguieventdispatcher.h"
#include "qwindowsmousehandler.h"
#include "qtwindowsglobal.h"
#include "qwindowsmime.h"
@@ -52,7 +51,6 @@
#endif
#include "qwindowsscreen.h"
#include "qwindowstheme.h"
-#include "qwindowsscaling.h"
#include <QtGui/QWindow>
#include <qpa/qwindowsysteminterface.h>
@@ -67,6 +65,8 @@
#include <QtCore/QScopedArrayPointer>
#include <QtCore/private/qsystemlibrary_p.h>
+#include <QtPlatformSupport/private/qwindowsguieventdispatcher_p.h>
+
#include <stdlib.h>
#include <stdio.h>
#include <windowsx.h>
@@ -177,7 +177,8 @@ QWindowsUser32DLL::QWindowsUser32DLL() :
isHungAppWindow(0), isTouchWindow(0),
registerTouchWindow(0), unregisterTouchWindow(0),
getTouchInputInfo(0), closeTouchInputHandle(0), setProcessDPIAware(0),
- addClipboardFormatListener(0), removeClipboardFormatListener(0)
+ addClipboardFormatListener(0), removeClipboardFormatListener(0),
+ getDisplayAutoRotationPreferences(0), setDisplayAutoRotationPreferences(0)
{
}
@@ -198,6 +199,8 @@ void QWindowsUser32DLL::init()
addClipboardFormatListener = (AddClipboardFormatListener)library.resolve("AddClipboardFormatListener");
removeClipboardFormatListener = (RemoveClipboardFormatListener)library.resolve("RemoveClipboardFormatListener");
}
+ getDisplayAutoRotationPreferences = (GetDisplayAutoRotationPreferences)library.resolve("GetDisplayAutoRotationPreferences");
+ setDisplayAutoRotationPreferences = (SetDisplayAutoRotationPreferences)library.resolve("SetDisplayAutoRotationPreferences");
}
bool QWindowsUser32DLL::initTouch()
@@ -402,14 +405,29 @@ void QWindowsContext::setTabletAbsoluteRange(int a)
#endif
}
+int QWindowsContext::processDpiAwareness()
+{
+#ifndef Q_OS_WINCE
+ int result;
+ if (QWindowsContext::shcoredll.getProcessDpiAwareness
+ && SUCCEEDED(QWindowsContext::shcoredll.getProcessDpiAwareness(NULL, &result))) {
+ return result;
+ }
+#endif // !Q_OS_WINCE
+ return -1;
+}
+
void QWindowsContext::setProcessDpiAwareness(QtWindows::ProcessDpiAwareness dpiAwareness)
{
#ifndef Q_OS_WINCE
qCDebug(lcQpaWindows) << __FUNCTION__ << dpiAwareness;
if (QWindowsContext::shcoredll.isValid()) {
const HRESULT hr = QWindowsContext::shcoredll.setProcessDpiAwareness(dpiAwareness);
- if (FAILED(hr))
- qWarning() << "SetProcessDpiAwareness failed:" << QWindowsContext::comErrorString(hr);
+ if (FAILED(hr)) {
+ qWarning().noquote().nospace() << "SetProcessDpiAwareness("
+ << dpiAwareness << ") failed: " << QWindowsContext::comErrorString(hr)
+ << ", using " << QWindowsContext::processDpiAwareness();
+ }
} else {
if (dpiAwareness != QtWindows::ProcessDpiUnaware && QWindowsContext::user32dll.setProcessDPIAware) {
if (!QWindowsContext::user32dll.setProcessDPIAware())
@@ -893,6 +911,11 @@ QByteArray QWindowsContext::comErrorString(HRESULT hr)
return result;
}
+static inline QWindowsInputContext *windowsInputContext()
+{
+ return qobject_cast<QWindowsInputContext *>(QWindowsIntegration::instance()->inputContext());
+}
+
/*!
\brief Main windows procedure registered for windows.
@@ -941,16 +964,29 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
return true;
}
}
+ if (et & QtWindows::InputMethodEventFlag) {
+ QWindowsInputContext *windowsInputContext = ::windowsInputContext();
+ // Disable IME assuming this is a special implementation hooking into keyboard input.
+ // "Real" IME implementations should use a native event filter intercepting IME events.
+ if (!windowsInputContext) {
+ QWindowsInputContext::setWindowsImeEnabled(platformWindow, false);
+ return false;
+ }
+ switch (et) {
+ case QtWindows::InputMethodStartCompositionEvent:
+ return windowsInputContext->startComposition(hwnd);
+ case QtWindows::InputMethodCompositionEvent:
+ return windowsInputContext->composition(hwnd, lParam);
+ case QtWindows::InputMethodEndCompositionEvent:
+ return windowsInputContext->endComposition(hwnd);
+ case QtWindows::InputMethodRequest:
+ return windowsInputContext->handleIME_Request(wParam, lParam, result);
+ default:
+ break;
+ }
+ } // InputMethodEventFlag
switch (et) {
- case QtWindows::InputMethodStartCompositionEvent:
- return QWindowsInputContext::instance()->startComposition(hwnd);
- case QtWindows::InputMethodCompositionEvent:
- return QWindowsInputContext::instance()->composition(hwnd, lParam);
- case QtWindows::InputMethodEndCompositionEvent:
- return QWindowsInputContext::instance()->endComposition(hwnd);
- case QtWindows::InputMethodRequest:
- return QWindowsInputContext::instance()->handleIME_Request(wParam, lParam, result);
case QtWindows::GestureEvent:
#if !defined(Q_OS_WINCE) && !defined(QT_NO_SESSIONMANAGER)
return platformSessionManager()->isInteractionBlocked() ? true : d->m_mouseHandler.translateGestureEvent(platformWindow->window(), hwnd, et, msg, result);
@@ -1025,11 +1061,13 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
}
switch (et) {
+ case QtWindows::KeyboardLayoutChangeEvent:
+ if (QWindowsInputContext *wic = windowsInputContext())
+ wic->handleInputLanguageChanged(wParam, lParam); // fallthrough intended.
case QtWindows::KeyDownEvent:
case QtWindows::KeyEvent:
case QtWindows::InputMethodKeyEvent:
case QtWindows::InputMethodKeyDownEvent:
- case QtWindows::KeyboardLayoutChangeEvent:
case QtWindows::AppCommandEvent:
#if !defined(Q_OS_WINCE) && !defined(QT_NO_SESSIONMANAGER)
return platformSessionManager()->isInteractionBlocked() ? true : d->m_keyMapper.translateKeyEvent(platformWindow->window(), hwnd, msg, result);
@@ -1265,9 +1303,7 @@ bool QWindowsContext::handleContextMenuEvent(QWindow *window, const MSG &msg)
}
}
- QWindowSystemInterface::handleContextMenuEvent(window, mouseTriggered,
- pos / QWindowsScaling::factor(),
- globalPos / QWindowsScaling::factor(),
+ QWindowSystemInterface::handleContextMenuEvent(window, mouseTriggered, pos, globalPos,
QWindowsKeyMapper::queryKeyboardModifiers());
return true;
}
diff --git a/src/plugins/platforms/windows/qwindowscontext.h b/src/plugins/platforms/windows/qwindowscontext.h
index 641e3ed41f..14baec96d8 100644
--- a/src/plugins/platforms/windows/qwindowscontext.h
+++ b/src/plugins/platforms/windows/qwindowscontext.h
@@ -94,6 +94,8 @@ struct QWindowsUser32DLL
typedef BOOL (WINAPI *SetProcessDPIAware)();
typedef BOOL (WINAPI *AddClipboardFormatListener)(HWND);
typedef BOOL (WINAPI *RemoveClipboardFormatListener)(HWND);
+ typedef BOOL (WINAPI *GetDisplayAutoRotationPreferences)(DWORD *);
+ typedef BOOL (WINAPI *SetDisplayAutoRotationPreferences)(DWORD);
// Functions missing in Q_CC_GNU stub libraries.
SetLayeredWindowAttributes setLayeredWindowAttributes;
@@ -116,6 +118,10 @@ struct QWindowsUser32DLL
// Clipboard listeners, Windows Vista onwards
AddClipboardFormatListener addClipboardFormatListener;
RemoveClipboardFormatListener removeClipboardFormatListener;
+
+ // Rotation API
+ GetDisplayAutoRotationPreferences getDisplayAutoRotationPreferences;
+ SetDisplayAutoRotationPreferences setDisplayAutoRotationPreferences;
};
struct QWindowsShell32DLL
@@ -142,7 +148,7 @@ struct QWindowsShcoreDLL {
void init();
inline bool isValid() const { return getProcessDpiAwareness && setProcessDpiAwareness && getDpiForMonitor; }
- typedef HRESULT (WINAPI *GetProcessDpiAwareness)(HANDLE,int);
+ typedef HRESULT (WINAPI *GetProcessDpiAwareness)(HANDLE,int *);
typedef HRESULT (WINAPI *SetProcessDpiAwareness)(int);
typedef HRESULT (WINAPI *GetDpiForMonitor)(HMONITOR,int,UINT *,UINT *);
@@ -213,6 +219,7 @@ public:
void setTabletAbsoluteRange(int a);
void setProcessDpiAwareness(QtWindows::ProcessDpiAwareness dpiAwareness);
+ static int processDpiAwareness();
// Returns a combination of SystemInfoFlags
unsigned systemInfo() const;
diff --git a/src/plugins/platforms/windows/qwindowscursor.cpp b/src/plugins/platforms/windows/qwindowscursor.cpp
index 5f443f2675..c769eb04a4 100644
--- a/src/plugins/platforms/windows/qwindowscursor.cpp
+++ b/src/plugins/platforms/windows/qwindowscursor.cpp
@@ -36,7 +36,6 @@
#include "qwindowscontext.h"
#include "qwindowswindow.h"
#include "qwindowsscreen.h"
-#include "qwindowsscaling.h"
#include <QtGui/QBitmap>
#include <QtGui/QImage>
@@ -44,15 +43,17 @@
#include <QtGui/QGuiApplication>
#include <QtGui/QScreen>
#include <QtGui/private/qguiapplication_p.h> // getPixmapCursor()
+#include <QtGui/private/qhighdpiscaling_p.h>
#include <QtCore/QDebug>
#include <QtCore/QScopedArrayPointer>
-static void initResources()
+static bool initResources()
{
#if !defined (Q_OS_WINCE) && !defined (QT_NO_IMAGEFORMAT_PNG)
Q_INIT_RESOURCE(cursors);
#endif
+ return true;
}
QT_BEGIN_NAMESPACE
@@ -68,19 +69,14 @@ Q_GUI_EXPORT HBITMAP qt_createIconMask(const QBitmap &bitmap);
\ingroup qt-lighthouse-win
*/
-QWindowsCursorCacheKey::QWindowsCursorCacheKey(const QCursor &c)
- : shape(c.shape()), bitmapCacheKey(0), maskCacheKey(0)
+QWindowsPixmapCursorCacheKey::QWindowsPixmapCursorCacheKey(const QCursor &c)
+ : bitmapCacheKey(c.pixmap().cacheKey()), maskCacheKey(0)
{
- if (shape == Qt::BitmapCursor) {
- const qint64 pixmapCacheKey = c.pixmap().cacheKey();
- if (pixmapCacheKey) {
- bitmapCacheKey = pixmapCacheKey;
- } else {
- Q_ASSERT(c.bitmap());
- Q_ASSERT(c.mask());
- bitmapCacheKey = c.bitmap()->cacheKey();
- maskCacheKey = c.mask()->cacheKey();
- }
+ if (!bitmapCacheKey) {
+ Q_ASSERT(c.bitmap());
+ Q_ASSERT(c.mask());
+ bitmapCacheKey = c.bitmap()->cacheKey();
+ maskCacheKey = c.mask()->cacheKey();
}
}
@@ -98,9 +94,14 @@ QWindowsCursorCacheKey::QWindowsCursorCacheKey(const QCursor &c)
\sa QWindowsWindowCursor
*/
-HCURSOR QWindowsCursor::createPixmapCursor(const QPixmap &pixmap, const QPoint &hotSpot)
+HCURSOR QWindowsCursor::createPixmapCursor(QPixmap pixmap, const QPoint &hotSpot, qreal scaleFactor)
{
HCURSOR cur = 0;
+ scaleFactor /= pixmap.devicePixelRatioF();
+ if (!qFuzzyCompare(scaleFactor, 1)) {
+ pixmap = pixmap.scaled((scaleFactor * QSizeF(pixmap.size())).toSize(),
+ Qt::KeepAspectRatio, Qt::SmoothTransformation);
+ }
QBitmap mask = pixmap.mask();
if (mask.isNull()) {
mask = QBitmap(pixmap.size());
@@ -207,7 +208,44 @@ static HCURSOR createBitmapCursor(const QImage &bbits, const QImage &mbits,
#endif
}
-static inline QSize systemCursorSize() { return QSize(GetSystemMetrics(SM_CXCURSOR), GetSystemMetrics(SM_CYCURSOR)); }
+// Create a cursor from image and mask of the format QImage::Format_Mono.
+static HCURSOR createBitmapCursor(const QCursor &cursor, qreal scaleFactor = 1)
+{
+ Q_ASSERT(cursor.shape() == Qt::BitmapCursor && cursor.bitmap());
+ QImage bbits = cursor.bitmap()->toImage();
+ QImage mbits = cursor.mask()->toImage();
+ scaleFactor /= bbits.devicePixelRatioF();
+ if (!qFuzzyCompare(scaleFactor, 1)) {
+ const QSize scaledSize = (QSizeF(bbits.size()) * scaleFactor).toSize();
+ bbits = bbits.scaled(scaledSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
+ mbits = mbits.scaled(scaledSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
+ }
+ bbits = bbits.convertToFormat(QImage::Format_Mono);
+ mbits = mbits.convertToFormat(QImage::Format_Mono);
+ const bool invb = bbits.colorCount() > 1 && qGray(bbits.color(0)) < qGray(bbits.color(1));
+ const bool invm = mbits.colorCount() > 1 && qGray(mbits.color(0)) < qGray(mbits.color(1));
+ return createBitmapCursor(bbits, mbits, cursor.hotSpot(), invb, invm);
+}
+
+static QSize systemCursorSize(const QPlatformScreen *screen = Q_NULLPTR)
+{
+ const QSize primaryScreenCursorSize(GetSystemMetrics(SM_CXCURSOR), GetSystemMetrics(SM_CYCURSOR));
+ if (screen) {
+ // Correct the size if the DPI value of the screen differs from
+ // that of the primary screen.
+ if (const QScreen *primaryQScreen = QGuiApplication::primaryScreen()) {
+ const QPlatformScreen *primaryScreen = primaryQScreen->handle();
+ if (screen != primaryScreen) {
+ const qreal logicalDpi = screen->logicalDpi().first;
+ const qreal primaryScreenLogicalDpi = primaryScreen->logicalDpi().first;
+ if (!qFuzzyCompare(logicalDpi, primaryScreenLogicalDpi))
+ return (QSizeF(primaryScreenCursorSize) * logicalDpi / primaryScreenLogicalDpi).toSize();
+ }
+ }
+ }
+ return primaryScreenCursorSize;
+}
+
static inline QSize standardCursorSize() { return QSize(32, 32); }
#if defined (Q_OS_WINCE) || defined (QT_NO_IMAGEFORMAT_PNG)
@@ -216,7 +254,7 @@ static inline QSize standardCursorSize() { return QSize(32, 32); }
// createBitmapCursor() only work for standard sizes (32,48,64...), which does
// not work when scaling the 16x16 openhand cursor bitmaps to 150% (resulting
// in a non-standard 24x24 size).
-static QCursor createPixmapCursorFromData(const QSize &systemCursorSize,
+static QWindowsCursor::PixmapCursor createPixmapCursorFromData(const QSize &systemCursorSize,
// The cursor size the bitmap is targeted for
const QSize &bitmapTargetCursorSize,
// The actual size of the bitmap data
@@ -234,10 +272,11 @@ static QCursor createPixmapCursorFromData(const QSize &systemCursorSize,
rawImage = rawImage.transformed(transform, Qt::SmoothTransformation);
}
const QPoint hotSpot(rawImage.width() / 2, rawImage.height() / 2);
- return QCursor(rawImage, hotSpot.x(), hotSpot.y());
+ return QWindowsCursor::PixmapCursor(rawImage, hotSpot);
}
-QCursor QWindowsCursor::customCursor(Qt::CursorShape cursorShape)
+QWindowsCursor::PixmapCursor QWindowsCursor::customCursor(Qt::CursorShape cursorShape,
+ const QPlatformScreen *screen)
{
// Non-standard Windows cursors are created from bitmaps
static const uchar vsplit_bits[] = {
@@ -405,22 +444,22 @@ QCursor QWindowsCursor::customCursor(Qt::CursorShape cursorShape)
switch (cursorShape) {
case Qt::SplitVCursor:
- return createPixmapCursorFromData(systemCursorSize(), standardCursorSize(), 32, vsplit_bits, vsplitm_bits);
+ return createPixmapCursorFromData(systemCursorSize(screen), standardCursorSize(), 32, vsplit_bits, vsplitm_bits);
case Qt::SplitHCursor:
- return createPixmapCursorFromData(systemCursorSize(), standardCursorSize(), 32, hsplit_bits, hsplitm_bits);
+ return createPixmapCursorFromData(systemCursorSize(screen), standardCursorSize(), 32, hsplit_bits, hsplitm_bits);
case Qt::OpenHandCursor:
- return createPixmapCursorFromData(systemCursorSize(), standardCursorSize(), 16, openhand_bits, openhandm_bits);
+ return createPixmapCursorFromData(systemCursorSize(screen), standardCursorSize(), 16, openhand_bits, openhandm_bits);
case Qt::ClosedHandCursor:
- return createPixmapCursorFromData(systemCursorSize(), standardCursorSize(), 16, closedhand_bits, closedhandm_bits);
+ return createPixmapCursorFromData(systemCursorSize(screen), standardCursorSize(), 16, closedhand_bits, closedhandm_bits);
case Qt::DragCopyCursor:
- return QCursor(QPixmap(copyDragCursorXpmC), 0, 0);
+ return QWindowsCursor::PixmapCursor(QPixmap(copyDragCursorXpmC), QPoint(0, 0));
case Qt::DragMoveCursor:
- return QCursor(QPixmap(moveDragCursorXpmC), 0, 0);
+ return QWindowsCursor::PixmapCursor(QPixmap(moveDragCursorXpmC), QPoint(0, 0));
case Qt::DragLinkCursor:
- return QCursor(QPixmap(linkDragCursorXpmC), 0, 0);
+ return QWindowsCursor::PixmapCursor(QPixmap(linkDragCursorXpmC), QPoint(0, 0));
}
- return QCursor();
+ return QWindowsCursor::PixmapCursor();
}
#else // Q_OS_WINCE || QT_NO_IMAGEFORMAT_PNG
struct QWindowsCustomPngCursor {
@@ -431,7 +470,7 @@ struct QWindowsCustomPngCursor {
int hotSpotY;
};
-QCursor QWindowsCursor::customCursor(Qt::CursorShape cursorShape)
+QWindowsCursor::PixmapCursor QWindowsCursor::customCursor(Qt::CursorShape cursorShape, const QPlatformScreen *screen)
{
static const QWindowsCustomPngCursor pngCursors[] = {
{ Qt::SplitVCursor, 32, "splitvcursor_32.png", 11, 11 },
@@ -457,14 +496,14 @@ QCursor QWindowsCursor::customCursor(Qt::CursorShape cursorShape)
{ Qt::DragLinkCursor, 64, "draglinkcursor_64.png", 0, 0 }
};
- const int cursorSize = GetSystemMetrics(SM_CXCURSOR);
+ const QSize cursorSize = systemCursorSize(screen);
const QWindowsCustomPngCursor *sEnd = pngCursors + sizeof(pngCursors) / sizeof(pngCursors[0]);
const QWindowsCustomPngCursor *bestFit = 0;
int sizeDelta = INT_MAX;
for (const QWindowsCustomPngCursor *s = pngCursors; s < sEnd; ++s) {
if (s->shape != cursorShape)
continue;
- const int currentSizeDelta = qMax(s->size, cursorSize) - qMin(s->size, cursorSize);
+ const int currentSizeDelta = qMax(s->size, cursorSize.width()) - qMin(s->size, cursorSize.width());
if (currentSizeDelta < sizeDelta) {
bestFit = s;
if (currentSizeDelta == 0)
@@ -474,11 +513,11 @@ QCursor QWindowsCursor::customCursor(Qt::CursorShape cursorShape)
}
if (!bestFit)
- return QCursor();
+ return PixmapCursor();
const QPixmap rawImage(QStringLiteral(":/qt-project.org/windows/cursors/images/") +
QString::fromLatin1(bestFit->fileName));
- return QCursor(rawImage, bestFit->hotSpotX, bestFit->hotSpotY);
+ return PixmapCursor(rawImage, QPoint(bestFit->hotSpotX, bestFit->hotSpotY));
}
#endif // Q_OS_WINCE || QT_NO_IMAGEFORMAT_PNG
@@ -487,8 +526,10 @@ struct QWindowsStandardCursorMapping {
LPCWSTR resource;
};
-HCURSOR QWindowsCursor::createSystemCursor(const QCursor &c)
+HCURSOR QWindowsCursor::createCursorFromShape(Qt::CursorShape cursorShape, const QPlatformScreen *screen)
{
+ Q_ASSERT(cursorShape != Qt::BitmapCursor);
+
static const QWindowsStandardCursorMapping standardCursors[] = {
{ Qt::ArrowCursor, IDC_ARROW},
{ Qt::UpArrowCursor, IDC_UPARROW },
@@ -506,20 +547,9 @@ HCURSOR QWindowsCursor::createSystemCursor(const QCursor &c)
{ Qt::PointingHandCursor, IDC_HAND }
};
- const Qt::CursorShape cursorShape = c.shape();
switch (cursorShape) {
- case Qt::BitmapCursor: {
- const QPixmap pixmap = c.pixmap();
- if (!pixmap.isNull())
- return QWindowsCursor::createPixmapCursor(pixmap, c.hotSpot());
- const QImage bbits = c.bitmap()->toImage().convertToFormat(QImage::Format_Mono);
- const QImage mbits = c.mask()->toImage().convertToFormat(QImage::Format_Mono);
- const bool invb = bbits.colorCount() > 1 && qGray(bbits.color(0)) < qGray(bbits.color(1));
- const bool invm = mbits.colorCount() > 1 && qGray(mbits.color(0)) < qGray(mbits.color(1));
- return createBitmapCursor(bbits, mbits, c.hotSpot(), invb, invm);
- }
case Qt::BlankCursor: {
- QImage blank = QImage(systemCursorSize(), QImage::Format_Mono);
+ QImage blank = QImage(systemCursorSize(screen), QImage::Format_Mono);
blank.fill(0); // ignore color table
return createBitmapCursor(blank, blank);
}
@@ -530,7 +560,7 @@ HCURSOR QWindowsCursor::createSystemCursor(const QCursor &c)
case Qt::DragCopyCursor:
case Qt::DragMoveCursor:
case Qt::DragLinkCursor:
- return createSystemCursor(customCursor(cursorShape));
+ return QWindowsCursor::createPixmapCursor(customCursor(cursorShape, screen));
default:
break;
}
@@ -555,44 +585,52 @@ HCURSOR QWindowsCursor::createSystemCursor(const QCursor &c)
\brief Return cached standard cursor resources or create new ones.
*/
-QWindowsWindowCursor QWindowsCursor::standardWindowCursor(Qt::CursorShape shape)
+CursorHandlePtr QWindowsCursor::standardWindowCursor(Qt::CursorShape shape)
{
- const QWindowsCursorCacheKey key(shape);
- CursorCache::iterator it = m_cursorCache.find(key);
- if (it == m_cursorCache.end())
- it = m_cursorCache.insert(key, QWindowsWindowCursor(QCursor(shape)));
- return it.value();
+ StandardCursorCache::Iterator it = m_standardCursorCache.find(shape);
+ if (it == m_standardCursorCache.end()) {
+ if (const HCURSOR hc = QWindowsCursor::createCursorFromShape(shape, m_screen))
+ it = m_standardCursorCache.insert(shape, CursorHandlePtr(new CursorHandle(hc)));
+ }
+ return it != m_standardCursorCache.end() ? it.value() : CursorHandlePtr(new CursorHandle);
}
/*!
\brief Return cached pixmap cursor or create new one.
*/
-QWindowsWindowCursor QWindowsCursor::pixmapWindowCursor(const QCursor &c)
+CursorHandlePtr QWindowsCursor::pixmapWindowCursor(const QCursor &c)
{
- const QWindowsCursorCacheKey cacheKey(c);
- CursorCache::iterator it = m_cursorCache.find(cacheKey);
- if (it == m_cursorCache.end()) {
- if (m_cursorCache.size() > 50) {
+ const QWindowsPixmapCursorCacheKey cacheKey(c);
+ PixmapCursorCache::iterator it = m_pixmapCursorCache.find(cacheKey);
+ if (it == m_pixmapCursorCache.end()) {
+ if (m_pixmapCursorCache.size() > 50) {
// Prevent the cursor cache from growing indefinitely hitting GDI resource
// limits if new pixmap cursors are created repetitively by purging out
// all-noncurrent pixmap cursors (QTBUG-43515)
const HCURSOR currentCursor = GetCursor();
- for (it = m_cursorCache.begin(); it != m_cursorCache.end() ; ) {
- if (it.key().bitmapCacheKey && it.value().handle() != currentCursor)
- it = m_cursorCache.erase(it);
+ for (it = m_pixmapCursorCache.begin(); it != m_pixmapCursorCache.end() ; ) {
+ if (it.value()->handle() != currentCursor)
+ it = m_pixmapCursorCache.erase(it);
else
++it;
}
}
- it = m_cursorCache.insert(cacheKey, QWindowsWindowCursor(c));
+ const qreal scaleFactor = QHighDpiScaling::factor(m_screen);
+ const QPixmap pixmap = c.pixmap();
+ const HCURSOR hc = pixmap.isNull()
+ ? createBitmapCursor(c, scaleFactor)
+ : QWindowsCursor::createPixmapCursor(pixmap, c.hotSpot(), scaleFactor);
+ it = m_pixmapCursorCache.insert(cacheKey, CursorHandlePtr(new CursorHandle(hc)));
}
return it.value();
}
-QWindowsCursor::QWindowsCursor()
+QWindowsCursor::QWindowsCursor(const QPlatformScreen *screen)
+ : m_screen(screen)
{
- initResources();
+ static const bool dummy = initResources();
+ Q_UNUSED(dummy)
}
/*!
@@ -607,13 +645,13 @@ void QWindowsCursor::changeCursor(QCursor *cursorIn, QWindow *window)
if (!window)
return;
if (!cursorIn) {
- QWindowsWindow::baseWindowOf(window)->setCursor(QWindowsWindowCursor());
+ QWindowsWindow::baseWindowOf(window)->setCursor(CursorHandlePtr(new CursorHandle));
return;
}
- const QWindowsWindowCursor wcursor =
+ const CursorHandlePtr wcursor =
cursorIn->shape() == Qt::BitmapCursor ?
pixmapWindowCursor(*cursorIn) : standardWindowCursor(cursorIn->shape());
- if (wcursor.handle()) {
+ if (wcursor->handle()) {
QWindowsWindow::baseWindowOf(window)->setCursor(wcursor);
} else {
qWarning("%s: Unable to obtain system cursor for %d",
@@ -646,13 +684,100 @@ QWindowsCursor::CursorState QWindowsCursor::cursorState()
QPoint QWindowsCursor::pos() const
{
- return mousePosition() / QWindowsScaling::factor();
+ return mousePosition();
}
void QWindowsCursor::setPos(const QPoint &pos)
{
- const QPoint posDp = pos * QWindowsScaling::factor();
- SetCursorPos(posDp.x() , posDp.y());
+ SetCursorPos(pos.x() , pos.y());
+}
+
+QPixmap QWindowsCursor::dragDefaultCursor(Qt::DropAction action) const
+{
+ switch (action) {
+ case Qt::CopyAction:
+ if (m_copyDragCursor.isNull())
+ m_copyDragCursor = QWindowsCursor::customCursor(Qt::DragCopyCursor, m_screen).pixmap;
+ return m_copyDragCursor;
+ case Qt::TargetMoveAction:
+ case Qt::MoveAction:
+ if (m_moveDragCursor.isNull())
+ m_moveDragCursor = QWindowsCursor::customCursor(Qt::DragMoveCursor, m_screen).pixmap;
+ return m_moveDragCursor;
+ case Qt::LinkAction:
+ if (m_linkDragCursor.isNull())
+ m_linkDragCursor = QWindowsCursor::customCursor(Qt::DragLinkCursor, m_screen).pixmap;
+ return m_linkDragCursor;
+ default:
+ break;
+ }
+
+ static const char * const ignoreDragCursorXpmC[] = {
+ "24 30 3 1",
+ ". c None",
+ "a c #000000",
+ "X c #FFFFFF",
+ "aa......................",
+ "aXa.....................",
+ "aXXa....................",
+ "aXXXa...................",
+ "aXXXXa..................",
+ "aXXXXXa.................",
+ "aXXXXXXa................",
+ "aXXXXXXXa...............",
+ "aXXXXXXXXa..............",
+ "aXXXXXXXXXa.............",
+ "aXXXXXXaaaa.............",
+ "aXXXaXXa................",
+ "aXXaaXXa................",
+ "aXa..aXXa...............",
+ "aa...aXXa...............",
+ "a.....aXXa..............",
+ "......aXXa.....XXXX.....",
+ ".......aXXa..XXaaaaXX...",
+ ".......aXXa.XaaaaaaaaX..",
+ "........aa.XaaaXXXXaaaX.",
+ "...........XaaaaX..XaaX.",
+ "..........XaaXaaaX..XaaX",
+ "..........XaaXXaaaX.XaaX",
+ "..........XaaX.XaaaXXaaX",
+ "..........XaaX..XaaaXaaX",
+ "...........XaaX..XaaaaX.",
+ "...........XaaaXXXXaaaX.",
+ "............XaaaaaaaaX..",
+ ".............XXaaaaXX...",
+ "...............XXXX....."};
+
+ if (m_ignoreDragCursor.isNull()) {
+#if !defined (Q_OS_WINCE)
+ HCURSOR cursor = LoadCursor(NULL, IDC_NO);
+ ICONINFO iconInfo = {0, 0, 0, 0, 0};
+ GetIconInfo(cursor, &iconInfo);
+ BITMAP bmColor = {0, 0, 0, 0, 0, 0, 0};
+
+ if (iconInfo.hbmColor
+ && GetObject(iconInfo.hbmColor, sizeof(BITMAP), &bmColor)
+ && bmColor.bmWidth == bmColor.bmWidthBytes / 4) {
+ const int colorBitsLength = bmColor.bmHeight * bmColor.bmWidthBytes;
+ uchar *colorBits = new uchar[colorBitsLength];
+ GetBitmapBits(iconInfo.hbmColor, colorBitsLength, colorBits);
+ const QImage colorImage(colorBits, bmColor.bmWidth, bmColor.bmHeight,
+ bmColor.bmWidthBytes, QImage::Format_ARGB32);
+
+ m_ignoreDragCursor = QPixmap::fromImage(colorImage);
+ delete [] colorBits;
+ } else {
+ m_ignoreDragCursor = QPixmap(ignoreDragCursorXpmC);
+ }
+
+ DeleteObject(iconInfo.hbmMask);
+ DeleteObject(iconInfo.hbmColor);
+ DestroyCursor(cursor);
+#else // !Q_OS_WINCE
+ m_ignoreDragCursor = QPixmap(ignoreDragCursorXpmC);
+#endif // !Q_OS_WINCE
+ }
+ return m_ignoreDragCursor;
}
/*!
@@ -660,78 +785,11 @@ void QWindowsCursor::setPos(const QPoint &pos)
\brief Per-Window cursor. Contains a QCursor and manages its associated system
cursor handle resource.
- Based on QSharedDataPointer, so that it can be passed around and
- used as a property of QWindowsBaseWindow.
-
\internal
\ingroup qt-lighthouse-win
\sa QWindowsCursor
*/
-class QWindowsWindowCursorData : public QSharedData
-{
-public:
- QWindowsWindowCursorData() : m_cursor(Qt::ArrowCursor), m_handle(0) {}
- explicit QWindowsWindowCursorData(const QCursor &c);
- ~QWindowsWindowCursorData();
-
- const QCursor m_cursor;
- const HCURSOR m_handle;
-};
-
-QWindowsWindowCursorData::QWindowsWindowCursorData(const QCursor &c) :
- m_cursor(c),
- m_handle(QWindowsCursor::createSystemCursor(c))
-{
-}
-
-QWindowsWindowCursorData::~QWindowsWindowCursorData()
-{
- if (m_handle)
- DestroyCursor(m_handle);
-}
-
-QWindowsWindowCursor::QWindowsWindowCursor() :
- m_data(new QWindowsWindowCursorData)
-{
-}
-
-QWindowsWindowCursor::QWindowsWindowCursor(const QCursor &c) :
- m_data(new QWindowsWindowCursorData(c))
-{
-}
-
-QWindowsWindowCursor::~QWindowsWindowCursor()
-{
-}
-
-QWindowsWindowCursor::QWindowsWindowCursor(const QWindowsWindowCursor &rhs) :
- m_data(rhs.m_data)
-{
-}
-
-QWindowsWindowCursor & QWindowsWindowCursor::operator =(const QWindowsWindowCursor &rhs)
-{
- if (this != &rhs)
- m_data.operator =(rhs.m_data);
- return *this;
-}
-
-bool QWindowsWindowCursor::isNull() const
-{
- return m_data->m_handle == 0;
-}
-
-QCursor QWindowsWindowCursor::cursor() const
-{
- return m_data->m_cursor;
-}
-
-HCURSOR QWindowsWindowCursor::handle() const
-{
- return m_data->m_handle;
-}
-
QT_END_NAMESPACE
#endif // !QT_NO_CURSOR
diff --git a/src/plugins/platforms/windows/qwindowscursor.h b/src/plugins/platforms/windows/qwindowscursor.h
index f1763ddd7d..e93f779f94 100644
--- a/src/plugins/platforms/windows/qwindowscursor.h
+++ b/src/plugins/platforms/windows/qwindowscursor.h
@@ -37,51 +37,49 @@
#include "qtwindows_additional.h"
#include <qpa/qplatformcursor.h>
-#include <QtCore/QSharedDataPointer>
+#include <QtCore/QSharedPointer>
#include <QtCore/QHash>
QT_BEGIN_NAMESPACE
-class QWindowsWindowCursorData;
-
-struct QWindowsCursorCacheKey
+struct QWindowsPixmapCursorCacheKey
{
- explicit QWindowsCursorCacheKey(const QCursor &c);
- explicit QWindowsCursorCacheKey(Qt::CursorShape s) : shape(s), bitmapCacheKey(0), maskCacheKey(0) {}
- QWindowsCursorCacheKey() : shape(Qt::CustomCursor), bitmapCacheKey(0), maskCacheKey(0) {}
+ explicit QWindowsPixmapCursorCacheKey(const QCursor &c);
- Qt::CursorShape shape;
qint64 bitmapCacheKey;
qint64 maskCacheKey;
};
-inline bool operator==(const QWindowsCursorCacheKey &k1, const QWindowsCursorCacheKey &k2)
+inline bool operator==(const QWindowsPixmapCursorCacheKey &k1, const QWindowsPixmapCursorCacheKey &k2)
{
- return k1.shape == k2.shape && k1.bitmapCacheKey == k2.bitmapCacheKey && k1.maskCacheKey == k2.maskCacheKey;
+ return k1.bitmapCacheKey == k2.bitmapCacheKey && k1.maskCacheKey == k2.maskCacheKey;
}
-inline uint qHash(const QWindowsCursorCacheKey &k, uint seed) Q_DECL_NOTHROW
+inline uint qHash(const QWindowsPixmapCursorCacheKey &k, uint seed) Q_DECL_NOTHROW
{
- return (uint(k.shape) + uint(k.bitmapCacheKey) + uint(k.maskCacheKey)) ^ seed;
+ return (uint(k.bitmapCacheKey) + uint(k.maskCacheKey)) ^ seed;
}
-class QWindowsWindowCursor
+class CursorHandle
{
+ Q_DISABLE_COPY(CursorHandle)
public:
- QWindowsWindowCursor();
- explicit QWindowsWindowCursor(const QCursor &c);
- ~QWindowsWindowCursor();
- QWindowsWindowCursor(const QWindowsWindowCursor &c);
- QWindowsWindowCursor &operator=(const QWindowsWindowCursor &c);
+ explicit CursorHandle(HCURSOR hcursor = Q_NULLPTR) : m_hcursor(hcursor) {}
+ ~CursorHandle()
+ {
+ if (m_hcursor)
+ DestroyCursor(m_hcursor);
+ }
- bool isNull() const;
- QCursor cursor() const;
- HCURSOR handle() const;
+ bool isNull() const { return !m_hcursor; }
+ HCURSOR handle() const { return m_hcursor; }
private:
- QSharedDataPointer<QWindowsWindowCursorData> m_data;
+ const HCURSOR m_hcursor;
};
+typedef QSharedPointer<CursorHandle> CursorHandlePtr;
+
class QWindowsCursor : public QPlatformCursor
{
public:
@@ -91,25 +89,44 @@ public:
CursorSuppressed // Cursor suppressed by touch interaction (Windows 8).
};
- QWindowsCursor();
+ struct PixmapCursor {
+ explicit PixmapCursor(const QPixmap &pix = QPixmap(), const QPoint &h = QPoint()) : pixmap(pix), hotSpot(h) {}
+
+ QPixmap pixmap;
+ QPoint hotSpot;
+ };
+
+ explicit QWindowsCursor(const QPlatformScreen *screen);
void changeCursor(QCursor * widgetCursor, QWindow * widget) Q_DECL_OVERRIDE;
QPoint pos() const Q_DECL_OVERRIDE;
void setPos(const QPoint &pos) Q_DECL_OVERRIDE;
- static HCURSOR createPixmapCursor(const QPixmap &pixmap, const QPoint &hotSpot);
- static HCURSOR createSystemCursor(const QCursor &c);
- static QCursor customCursor(Qt::CursorShape cursorShape);
+ static HCURSOR createPixmapCursor(QPixmap pixmap, const QPoint &hotSpot, qreal scaleFactor = 1);
+ static HCURSOR createPixmapCursor(const PixmapCursor &pc, qreal scaleFactor = 1) { return createPixmapCursor(pc.pixmap, pc.hotSpot, scaleFactor); }
+ static PixmapCursor customCursor(Qt::CursorShape cursorShape, const QPlatformScreen *screen = Q_NULLPTR);
+
+ static HCURSOR createCursorFromShape(Qt::CursorShape cursorShape, const QPlatformScreen *screen = Q_NULLPTR);
static QPoint mousePosition();
static CursorState cursorState();
- QWindowsWindowCursor standardWindowCursor(Qt::CursorShape s = Qt::ArrowCursor);
- QWindowsWindowCursor pixmapWindowCursor(const QCursor &c);
+ CursorHandlePtr standardWindowCursor(Qt::CursorShape s = Qt::ArrowCursor);
+ CursorHandlePtr pixmapWindowCursor(const QCursor &c);
+
+ QPixmap dragDefaultCursor(Qt::DropAction action) const;
private:
- typedef QHash<QWindowsCursorCacheKey, QWindowsWindowCursor> CursorCache;
+ typedef QHash<Qt::CursorShape, CursorHandlePtr> StandardCursorCache;
+ typedef QHash<QWindowsPixmapCursorCacheKey, CursorHandlePtr> PixmapCursorCache;
+
+ const QPlatformScreen *const m_screen;
+ StandardCursorCache m_standardCursorCache;
+ PixmapCursorCache m_pixmapCursorCache;
- CursorCache m_cursorCache;
+ mutable QPixmap m_copyDragCursor;
+ mutable QPixmap m_moveDragCursor;
+ mutable QPixmap m_linkDragCursor;
+ mutable QPixmap m_ignoreDragCursor;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
index da0ba27e3a..9211fd1320 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)
@@ -874,12 +876,12 @@ public:
inline static QWindowsNativeFileDialogBase *create(QFileDialogOptions::AcceptMode am, const QWindowsFileDialogSharedData &data);
- virtual void setWindowTitle(const QString &title);
+ void setWindowTitle(const QString &title) Q_DECL_OVERRIDE;
inline void setMode(QFileDialogOptions::FileMode mode, QFileDialogOptions::AcceptMode acceptMode, QFileDialogOptions::FileDialogOptions options);
inline void setDirectory(const QUrl &directory);
inline void updateDirectory() { setDirectory(m_data.directory()); }
inline QString directory() const;
- virtual void doExec(HWND owner = 0);
+ void doExec(HWND owner = 0) Q_DECL_OVERRIDE;
virtual void setNameFilters(const QStringList &f);
inline void selectNameFilter(const QString &filter);
inline void updateSelectedNameFilter() { selectNameFilter(m_data.selectedNameFilter()); }
@@ -908,7 +910,7 @@ signals:
void filterSelected(const QString & filter);
public slots:
- virtual void close();
+ void close() Q_DECL_OVERRIDE;
protected:
explicit QWindowsNativeFileDialogBase(const QWindowsFileDialogSharedData &data);
@@ -1458,9 +1460,9 @@ class QWindowsNativeSaveFileDialog : public QWindowsNativeFileDialogBase
public:
explicit QWindowsNativeSaveFileDialog(const QWindowsFileDialogSharedData &data)
: QWindowsNativeFileDialogBase(data) {}
- virtual void setNameFilters(const QStringList &f);
- virtual QList<QUrl> selectedFiles() const;
- virtual QList<QUrl> dialogResult() const;
+ void setNameFilters(const QStringList &f) Q_DECL_OVERRIDE;
+ QList<QUrl> selectedFiles() const Q_DECL_OVERRIDE;
+ QList<QUrl> dialogResult() const Q_DECL_OVERRIDE;
};
// Return the first suffix from the name filter "Foo files (*.foo;*.bar)" -> "foo".
@@ -1529,8 +1531,8 @@ class QWindowsNativeOpenFileDialog : public QWindowsNativeFileDialogBase
public:
explicit QWindowsNativeOpenFileDialog(const QWindowsFileDialogSharedData &data) :
QWindowsNativeFileDialogBase(data) {}
- virtual QList<QUrl> selectedFiles() const;
- virtual QList<QUrl> dialogResult() const;
+ QList<QUrl> selectedFiles() const Q_DECL_OVERRIDE;
+ QList<QUrl> dialogResult() const Q_DECL_OVERRIDE;
private:
inline IFileOpenDialog *openFileDialog() const
@@ -1614,7 +1616,7 @@ public:
virtual QString selectedNameFilter() const Q_DECL_OVERRIDE;
private:
- virtual QWindowsNativeDialogBase *createNativeDialog();
+ QWindowsNativeDialogBase *createNativeDialog() Q_DECL_OVERRIDE;
inline QWindowsNativeFileDialogBase *nativeFileDialog() const
{ return static_cast<QWindowsNativeFileDialogBase *>(nativeDialog()); }
@@ -1742,14 +1744,13 @@ public:
static QWindowsXpNativeFileDialog *create(const OptionsPtr &options, const QWindowsFileDialogSharedData &data);
- virtual void setWindowTitle(const QString &t) { m_title = t; }
- virtual void doExec(HWND owner = 0);
- virtual QPlatformDialogHelper::DialogCode result() const { return m_result; }
+ void setWindowTitle(const QString &t) Q_DECL_OVERRIDE { m_title = t; }
+ void doExec(HWND owner = 0) Q_DECL_OVERRIDE;
int existingDirCallback(HWND hwnd, UINT uMsg, LPARAM lParam);
public slots:
- virtual void close() {}
+ void close() Q_DECL_OVERRIDE {}
private:
typedef BOOL (APIENTRY *PtrGetOpenFileNameW)(LPOPENFILENAMEW);
@@ -1985,19 +1986,19 @@ class QWindowsXpFileDialogHelper : public QWindowsDialogHelperBase<QPlatformFile
{
public:
QWindowsXpFileDialogHelper() {}
- virtual bool supportsNonModalDialog(const QWindow * /* parent */ = 0) const { return false; }
- virtual bool defaultNameFilterDisables() const
+ bool supportsNonModalDialog(const QWindow * /* parent */ = 0) const Q_DECL_OVERRIDE { return false; }
+ bool defaultNameFilterDisables() const Q_DECL_OVERRIDE
{ return true; }
- virtual void setDirectory(const QUrl &directory) Q_DECL_OVERRIDE;
- virtual QUrl directory() const Q_DECL_OVERRIDE;
- virtual void selectFile(const QUrl &url) Q_DECL_OVERRIDE;
- virtual QList<QUrl> selectedFiles() const Q_DECL_OVERRIDE;
- virtual void setFilter() Q_DECL_OVERRIDE {}
- virtual void selectNameFilter(const QString &) Q_DECL_OVERRIDE;
- virtual QString selectedNameFilter() const Q_DECL_OVERRIDE;
+ void setDirectory(const QUrl &directory) Q_DECL_OVERRIDE;
+ QUrl directory() const Q_DECL_OVERRIDE;
+ void selectFile(const QUrl &url) Q_DECL_OVERRIDE;
+ QList<QUrl> selectedFiles() const Q_DECL_OVERRIDE;
+ void setFilter() Q_DECL_OVERRIDE {}
+ void selectNameFilter(const QString &) Q_DECL_OVERRIDE;
+ QString selectedNameFilter() const Q_DECL_OVERRIDE;
private:
- virtual QWindowsNativeDialogBase *createNativeDialog();
+ QWindowsNativeDialogBase *createNativeDialog() Q_DECL_OVERRIDE;
inline QWindowsXpNativeFileDialog *nativeFileDialog() const
{ return static_cast<QWindowsXpNativeFileDialog *>(nativeDialog()); }
@@ -2071,14 +2072,13 @@ public:
explicit QWindowsNativeColorDialog(const SharedPointerColor &color);
- virtual void setWindowTitle(const QString &) {}
- virtual QPlatformDialogHelper::DialogCode result() const { return m_code; }
+ void setWindowTitle(const QString &) Q_DECL_OVERRIDE {}
public slots:
- virtual void close() {}
+ void close() Q_DECL_OVERRIDE {}
private:
- virtual void doExec(HWND owner = 0);
+ void doExec(HWND owner = 0) Q_DECL_OVERRIDE;
COLORREF m_customColors[CustomColorCount];
QPlatformDialogHelper::DialogCode m_code;
diff --git a/src/plugins/platforms/windows/qwindowsdrag.cpp b/src/plugins/platforms/windows/qwindowsdrag.cpp
index 03438e3ee2..16079576a2 100644
--- a/src/plugins/platforms/windows/qwindowsdrag.cpp
+++ b/src/plugins/platforms/windows/qwindowsdrag.cpp
@@ -33,7 +33,7 @@
#include "qwindowsdrag.h"
#include "qwindowscontext.h"
-#include "qwindowsscaling.h"
+#include "qwindowsscreen.h"
#ifndef QT_NO_CLIPBOARD
# include "qwindowsclipboard.h"
#endif
@@ -43,7 +43,6 @@
#include "qwindowswindow.h"
#include "qwindowsmousehandler.h"
#include "qwindowscursor.h"
-#include "qwindowsscaling.h"
#include <QtGui/QMouseEvent>
#include <QtGui/QPixmap>
@@ -52,6 +51,7 @@
#include <QtGui/QGuiApplication>
#include <qpa/qwindowsysteminterface_p.h>
#include <QtGui/private/qguiapplication_p.h>
+#include <QtGui/private/qhighdpiscaling_p.h>
#include <QtCore/QDebug>
#include <QtCore/QBuffer>
@@ -78,7 +78,7 @@ public:
void setPixmap(const QPixmap &p);
protected:
- void paintEvent(QPaintEvent *)
+ void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE
{
QPainter painter(this);
painter.drawPixmap(0, 0, m_pixmap);
@@ -218,23 +218,14 @@ public:
STDMETHOD(GiveFeedback)(DWORD dwEffect);
private:
- class DragCursorHandle {
- Q_DISABLE_COPY(DragCursorHandle)
- public:
- DragCursorHandle(HCURSOR c) : cursor(c) {}
- ~DragCursorHandle() { DestroyCursor(cursor); }
- const HCURSOR cursor;
- };
- typedef QSharedPointer<DragCursorHandle> DragCursorHandlePtr;
-
struct CursorEntry {
CursorEntry() : cacheKey(0) {}
- CursorEntry(const QPixmap &p, qint64 cK, const DragCursorHandlePtr &c, const QPoint &h) :
+ CursorEntry(const QPixmap &p, qint64 cK, const CursorHandlePtr &c, const QPoint &h) :
pixmap(p), cacheKey(cK), cursor(c), hotSpot(h) {}
QPixmap pixmap;
qint64 cacheKey; // Cache key of cursor
- DragCursorHandlePtr cursor;
+ CursorHandlePtr cursor;
QPoint hotSpot;
};
@@ -249,7 +240,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
};
@@ -271,14 +262,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;
+ << "HCURSOR" << e.cursor->handle() << "hotspot:" << e.hotSpot;
return d;
}
-#endif // !QT_NO_DEBUG_OUTPUT
+#endif // !QT_NO_DEBUG_STREAM
/*!
\brief Blend custom pixmap with cursors.
@@ -289,24 +280,37 @@ void QWindowsOleDropSource::createCursors()
const QDrag *drag = m_drag->currentDrag();
const QPixmap pixmap = drag->pixmap();
const bool hasPixmap = !pixmap.isNull();
- const int scaleFactor = QWindowsScaling::factor();
- const QSize pixmapSizeDp = pixmap.size() * scaleFactor;
+
+ // Find screen for drag. Could be obtained from QDrag::source(), but that might be a QWidget.
+
+ qreal scaleFactor = 1;
+ QPlatformCursor *platformCursor = Q_NULLPTR;
+ if (const QPlatformScreen *platformScreen = QWindowsContext::instance()->screenManager().screenAtDp(QWindowsCursor::mousePosition())) {
+ scaleFactor = QHighDpiScaling::factor(platformScreen);
+ platformCursor = platformScreen->cursor();
+ }
+ if (!platformCursor && QGuiApplication::primaryScreen())
+ platformCursor = QGuiApplication::primaryScreen()->handle()->cursor();
+
const bool scalePixmap = hasPixmap
&& m_mode != TouchDrag // Touch drag: pixmap is shown in a separate QWindow, which will be scaled.
&& (scaleFactor != 1 && scaleFactor != qRound(pixmap.devicePixelRatio()));
- const QPixmap drawPixmap = scalePixmap
- ? pixmap.scaled(pixmapSizeDp, Qt::KeepAspectRatio, Qt::SmoothTransformation) : pixmap;
-
+ const QPixmap scaledPixmap = scalePixmap
+ ? pixmap.scaled((QSizeF(pixmap.size()) * scaleFactor).toSize(),
+ Qt::KeepAspectRatio, Qt::SmoothTransformation)
+ : pixmap;
Qt::DropAction actions[] = { Qt::MoveAction, Qt::CopyAction, Qt::LinkAction, Qt::IgnoreAction };
int actionCount = int(sizeof(actions) / sizeof(actions[0]));
if (!hasPixmap)
--actionCount; // No Qt::IgnoreAction unless pixmap
- const QPoint hotSpot = drag->hotSpot() * scaleFactor;
+ const QPoint hotSpot = scalePixmap
+ ? (QPointF(drag->hotSpot()) * scaleFactor).toPoint()
+ : drag->hotSpot();
for (int cnum = 0; cnum < actionCount; ++cnum) {
const Qt::DropAction action = actions[cnum];
QPixmap cursorPixmap = drag->dragCursor(action);
- if (cursorPixmap.isNull())
- cursorPixmap = m_drag->defaultCursor(action);
+ if (cursorPixmap.isNull() && platformCursor)
+ cursorPixmap = static_cast<QWindowsCursor *>(platformCursor)->dragDefaultCursor(action);
const qint64 cacheKey = cursorPixmap.cacheKey();
const ActionCursorMapIt it = m_cursors.find(action);
if (it != m_cursors.end() && it.value().cacheKey == cacheKey)
@@ -321,21 +325,21 @@ void QWindowsOleDropSource::createCursors()
if (hasPixmap) {
const int x1 = qMin(-hotSpot.x(), 0);
- const int x2 = qMax(pixmapSizeDp.width() - hotSpot.x(), cursorPixmap.width());
+ const int x2 = qMax(scaledPixmap.width() - hotSpot.x(), cursorPixmap.width());
const int y1 = qMin(-hotSpot.y(), 0);
- const int y2 = qMax(pixmapSizeDp.height() - hotSpot.y(), cursorPixmap.height());
+ const int y2 = qMax(scaledPixmap.height() - hotSpot.y(), cursorPixmap.height());
QPixmap newCursor(x2 - x1 + 1, y2 - y1 + 1);
newCursor.fill(Qt::transparent);
QPainter p(&newCursor);
const QPoint pmDest = QPoint(qMax(0, -hotSpot.x()), qMax(0, -hotSpot.y()));
- p.drawPixmap(pmDest, drawPixmap);
+ p.drawPixmap(pmDest, scaledPixmap);
p.drawPixmap(qMax(0, hotSpot.x()),qMax(0, hotSpot.y()), cursorPixmap);
newPixmap = newCursor;
newHotSpot = QPoint(qMax(0, hotSpot.x()), qMax(0, hotSpot.y()));
}
if (const HCURSOR sysCursor = QWindowsCursor::createPixmapCursor(newPixmap, newHotSpot)) {
- const CursorEntry entry(newPixmap, cacheKey, DragCursorHandlePtr(new DragCursorHandle(sysCursor)), newHotSpot);
+ const CursorEntry entry(newPixmap, cacheKey, CursorHandlePtr(new CursorHandle(sysCursor)), newHotSpot);
if (it == m_cursors.end())
m_cursors.insert(action, entry);
else
@@ -448,13 +452,13 @@ QWindowsOleDropSource::GiveFeedback(DWORD dwEffect)
const CursorEntry &e = it.value();
switch (m_mode) {
case MouseDrag:
- SetCursor(e.cursor->cursor);
+ SetCursor(e.cursor->handle());
break;
case TouchDrag:
if (!m_touchDragWindow)
m_touchDragWindow = new QWindowsDragCursorWindow;
m_touchDragWindow->setPixmap(e.pixmap);
- m_touchDragWindow->setFramePosition((QWindowsCursor::mousePosition() - e.hotSpot) / QWindowsScaling::factor());
+ m_touchDragWindow->setFramePosition(QWindowsCursor::mousePosition() - e.hotSpot);
if (!m_touchDragWindow->isVisible())
m_touchDragWindow->show();
break;
@@ -530,9 +534,7 @@ void QWindowsOleDropTarget::handleDrag(QWindow *window, DWORD grfKeyState,
QGuiApplicationPrivate::mouse_buttons = QWindowsMouseHandler::keyStateToMouseButtons(grfKeyState);
const QPlatformDragQtResponse response =
- QWindowSystemInterface::handleDrag(window, windowsDrag->dropData(),
- m_lastPoint / QWindowsScaling::factor(),
- actions);
+ QWindowSystemInterface::handleDrag(window, windowsDrag->dropData(), m_lastPoint, actions);
m_answerRect = response.answerRect();
const Qt::DropAction action = response.acceptedAction();
@@ -625,9 +627,8 @@ QWindowsOleDropTarget::Drop(LPDATAOBJECT pDataObj, DWORD grfKeyState,
const QPlatformDropQtResponse response =
QWindowSystemInterface::handleDrop(m_window, windowsDrag->dropData(),
- m_lastPoint / QWindowsScaling::factor(),
+ m_lastPoint,
translateToQDragDropActions(*pdwEffect));
-
if (response.isAccepted()) {
const Qt::DropAction action = response.acceptedAction();
if (action == Qt::MoveAction || action == Qt::TargetMoveAction) {
@@ -706,94 +707,6 @@ IDropTargetHelper* QWindowsDrag::dropHelper() {
return m_cachedDropTargetHelper;
}
-QPixmap QWindowsDrag::defaultCursor(Qt::DropAction action) const
-{
- switch (action) {
- case Qt::CopyAction:
- if (m_copyDragCursor.isNull())
- m_copyDragCursor = QWindowsCursor::customCursor(Qt::DragCopyCursor).pixmap();
- return m_copyDragCursor;
- case Qt::TargetMoveAction:
- case Qt::MoveAction:
- if (m_moveDragCursor.isNull())
- m_moveDragCursor = QWindowsCursor::customCursor(Qt::DragMoveCursor).pixmap();
- return m_moveDragCursor;
- case Qt::LinkAction:
- if (m_linkDragCursor.isNull())
- m_linkDragCursor = QWindowsCursor::customCursor(Qt::DragLinkCursor).pixmap();
- return m_linkDragCursor;
- default:
- break;
- }
-
- static const char * const ignoreDragCursorXpmC[] = {
- "24 30 3 1",
- ". c None",
- "a c #000000",
- "X c #FFFFFF",
- "aa......................",
- "aXa.....................",
- "aXXa....................",
- "aXXXa...................",
- "aXXXXa..................",
- "aXXXXXa.................",
- "aXXXXXXa................",
- "aXXXXXXXa...............",
- "aXXXXXXXXa..............",
- "aXXXXXXXXXa.............",
- "aXXXXXXaaaa.............",
- "aXXXaXXa................",
- "aXXaaXXa................",
- "aXa..aXXa...............",
- "aa...aXXa...............",
- "a.....aXXa..............",
- "......aXXa.....XXXX.....",
- ".......aXXa..XXaaaaXX...",
- ".......aXXa.XaaaaaaaaX..",
- "........aa.XaaaXXXXaaaX.",
- "...........XaaaaX..XaaX.",
- "..........XaaXaaaX..XaaX",
- "..........XaaXXaaaX.XaaX",
- "..........XaaX.XaaaXXaaX",
- "..........XaaX..XaaaXaaX",
- "...........XaaX..XaaaaX.",
- "...........XaaaXXXXaaaX.",
- "............XaaaaaaaaX..",
- ".............XXaaaaXX...",
- "...............XXXX....."};
-
- if (m_ignoreDragCursor.isNull()) {
-#if !defined (Q_OS_WINCE)
- HCURSOR cursor = LoadCursor(NULL, IDC_NO);
- ICONINFO iconInfo = {0, 0, 0, 0, 0};
- GetIconInfo(cursor, &iconInfo);
- BITMAP bmColor = {0, 0, 0, 0, 0, 0, 0};
-
- if (iconInfo.hbmColor
- && GetObject(iconInfo.hbmColor, sizeof(BITMAP), &bmColor)
- && bmColor.bmWidth == bmColor.bmWidthBytes / 4) {
- const int colorBitsLength = bmColor.bmHeight * bmColor.bmWidthBytes;
- uchar *colorBits = new uchar[colorBitsLength];
- GetBitmapBits(iconInfo.hbmColor, colorBitsLength, colorBits);
- const QImage colorImage(colorBits, bmColor.bmWidth, bmColor.bmHeight,
- bmColor.bmWidthBytes, QImage::Format_ARGB32);
-
- m_ignoreDragCursor = QPixmap::fromImage(colorImage);
- delete [] colorBits;
- } else {
- m_ignoreDragCursor = QPixmap(ignoreDragCursorXpmC);
- }
-
- DeleteObject(iconInfo.hbmMask);
- DeleteObject(iconInfo.hbmColor);
- DestroyCursor(cursor);
-#else // !Q_OS_WINCE
- m_ignoreDragCursor = QPixmap(ignoreDragCursorXpmC);
-#endif // !Q_OS_WINCE
- }
- return m_ignoreDragCursor;
-}
-
Qt::DropAction QWindowsDrag::drag(QDrag *drag)
{
// TODO: Accessibility handling?
diff --git a/src/plugins/platforms/windows/qwindowsdrag.h b/src/plugins/platforms/windows/qwindowsdrag.h
index 9a5e0b17f2..890ad6c142 100644
--- a/src/plugins/platforms/windows/qwindowsdrag.h
+++ b/src/plugins/platforms/windows/qwindowsdrag.h
@@ -42,6 +42,9 @@
struct IDropTargetHelper;
QT_BEGIN_NAMESPACE
+
+class QPlatformScreen;
+
class QWindowsDropMimeData : public QWindowsInternalMimeData {
public:
QWindowsDropMimeData() {}
@@ -95,18 +98,11 @@ public:
IDropTargetHelper* dropHelper();
- QPixmap defaultCursor(Qt::DropAction action) const;
-
private:
QWindowsDropMimeData m_dropData;
IDataObject *m_dropDataObject;
IDropTargetHelper* m_cachedDropTargetHelper;
-
- mutable QPixmap m_copyDragCursor;
- mutable QPixmap m_moveDragCursor;
- mutable QPixmap m_linkDragCursor;
- mutable QPixmap m_ignoreDragCursor;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowseglcontext.cpp b/src/plugins/platforms/windows/qwindowseglcontext.cpp
index f2547d5cdd..65a9763be6 100644
--- a/src/plugins/platforms/windows/qwindowseglcontext.cpp
+++ b/src/plugins/platforms/windows/qwindowseglcontext.cpp
@@ -39,7 +39,7 @@
#include <QtGui/QOpenGLContext>
#if defined(QT_OPENGL_ES_2_ANGLE) || defined(QT_OPENGL_DYNAMIC)
-# include <QtANGLE/EGL/eglext.h>
+# include <EGL/eglext.h>
#endif
QT_BEGIN_NAMESPACE
@@ -118,11 +118,11 @@ void *QWindowsLibEGL::resolve(const char *name)
bool QWindowsLibEGL::init()
{
-#ifdef QT_DEBUG
- const char dllName[] = "libEGLd.dll";
-#else
- const char dllName[] = "libEGL.dll";
+ const char dllName[] = QT_STRINGIFY(LIBEGL_NAME)
+#if defined(QT_DEBUG) && !defined(Q_OS_WINCE)
+ "d"
#endif
+ "";
qCDebug(lcQpaGl) << "Qt: Using EGL from" << dllName;
@@ -178,11 +178,12 @@ void *QWindowsLibGLESv2::resolve(const char *name)
bool QWindowsLibGLESv2::init()
{
-#ifdef QT_DEBUG
- const char dllName[] = "libGLESv2d.dll";
-#else
- const char dllName[] = "libGLESv2.dll";
+
+ const char dllName[] = QT_STRINGIFY(LIBGLESV2_NAME)
+#if defined(QT_DEBUG) && !defined(Q_OS_WINCE)
+ "d"
#endif
+ "";
qCDebug(lcQpaGl) << "Qt: Using OpenGL ES 2.0 from" << dllName;
#if !defined(QT_STATIC) || defined(QT_OPENGL_DYNAMIC)
@@ -350,16 +351,16 @@ QWindowsEGLStaticContext *QWindowsEGLStaticContext::create(QWindowsOpenGLTester:
{
const HDC dc = QWindowsContext::instance()->displayContext();
if (!dc){
- qWarning("%s: No Display", Q_FUNC_INFO);
+ qWarning("%s: No Display", __FUNCTION__);
return 0;
}
if (!libEGL.init()) {
- qWarning("%s: Failed to load and resolve libEGL functions", Q_FUNC_INFO);
+ qWarning("%s: Failed to load and resolve libEGL functions", __FUNCTION__);
return 0;
}
if (!libGLESv2.init()) {
- qWarning("%s: Failed to load and resolve libGLESv2 functions", Q_FUNC_INFO);
+ qWarning("%s: Failed to load and resolve libGLESv2 functions", __FUNCTION__);
return 0;
}
@@ -396,15 +397,15 @@ QWindowsEGLStaticContext *QWindowsEGLStaticContext::create(QWindowsOpenGLTester:
if (display == EGL_NO_DISPLAY)
display = libEGL.eglGetDisplay((EGLNativeDisplayType)dc);
if (!display) {
- qWarning("%s: Could not obtain EGL display", Q_FUNC_INFO);
+ qWarning("%s: Could not obtain EGL display", __FUNCTION__);
return 0;
}
if (!major && !libEGL.eglInitialize(display, &major, &minor)) {
int err = libEGL.eglGetError();
- qWarning("%s: Could not initialize EGL display: error 0x%x\n", Q_FUNC_INFO, err);
+ qWarning("%s: Could not initialize EGL display: error 0x%x", __FUNCTION__, err);
if (err == 0x3001)
- qWarning("%s: When using ANGLE, check if d3dcompiler_4x.dll is available", Q_FUNC_INFO);
+ qWarning("%s: When using ANGLE, check if d3dcompiler_4x.dll is available", __FUNCTION__);
return 0;
}
@@ -430,7 +431,7 @@ void *QWindowsEGLStaticContext::createWindowSurface(void *nativeWindow, void *na
(EGLNativeWindowType) nativeWindow, 0);
if (surface == EGL_NO_SURFACE) {
*err = libEGL.eglGetError();
- qWarning("%s: Could not create the EGL window surface: 0x%x\n", Q_FUNC_INFO, *err);
+ qWarning("%s: Could not create the EGL window surface: 0x%x", __FUNCTION__, *err);
}
return surface;
@@ -533,7 +534,12 @@ QWindowsEGLContext::QWindowsEGLContext(QWindowsEGLStaticContext *staticContext,
}
if (m_eglContext == EGL_NO_CONTEXT) {
- qWarning("QWindowsEGLContext: eglError: %x, this: %p \n", QWindowsEGLStaticContext::libEGL.eglGetError(), this);
+ int err = QWindowsEGLStaticContext::libEGL.eglGetError();
+ qWarning("QWindowsEGLContext: Failed to create context, eglError: %x, this: %p", err, this);
+ // ANGLE gives bad alloc when it fails to reset a previously lost D3D device.
+ // A common cause for this is disabling the graphics adapter used by the app.
+ if (err == EGL_BAD_ALLOC)
+ qWarning("QWindowsEGLContext: Graphics device lost. (Did the adapter get disabled?)");
return;
}
@@ -594,6 +600,12 @@ bool QWindowsEGLContext::makeCurrent(QPlatformSurface *surface)
if (err == EGL_CONTEXT_LOST) {
m_eglContext = EGL_NO_CONTEXT;
qCDebug(lcQpaGl) << "Got EGL context lost in createWindowSurface() for context" << this;
+ } else if (err == EGL_BAD_ACCESS) {
+ // With ANGLE this means no (D3D) device and can happen when disabling/changing graphics adapters.
+ qCDebug(lcQpaGl) << "Bad access (missing device?) in createWindowSurface() for context" << this;
+ // Simulate context loss as the context is useless.
+ QWindowsEGLStaticContext::libEGL.eglDestroyContext(m_eglDisplay, m_eglContext);
+ m_eglContext = EGL_NO_CONTEXT;
}
return false;
}
@@ -623,7 +635,7 @@ bool QWindowsEGLContext::makeCurrent(QPlatformSurface *surface)
// Drop the surface. Will recreate on the next makeCurrent.
window->invalidateSurface();
} else {
- qWarning("QWindowsEGLContext::makeCurrent: eglError: %x, this: %p \n", err, this);
+ qWarning("%s: Failed to make surface current. eglError: %x, this: %p", __FUNCTION__, err, this);
}
}
@@ -635,7 +647,8 @@ void QWindowsEGLContext::doneCurrent()
QWindowsEGLStaticContext::libEGL.eglBindAPI(m_api);
bool ok = QWindowsEGLStaticContext::libEGL.eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
if (!ok)
- qWarning("QWindowsEGLContext::doneCurrent: eglError: %d, this: %p \n", QWindowsEGLStaticContext::libEGL.eglGetError(), this);
+ qWarning("%s: Failed to make no context/surface current. eglError: %d, this: %p", __FUNCTION__,
+ QWindowsEGLStaticContext::libEGL.eglGetError(), this);
}
void QWindowsEGLContext::swapBuffers(QPlatformSurface *surface)
@@ -653,8 +666,15 @@ void QWindowsEGLContext::swapBuffers(QPlatformSurface *surface)
}
bool ok = QWindowsEGLStaticContext::libEGL.eglSwapBuffers(m_eglDisplay, eglSurface);
- if (!ok)
- qWarning("QWindowsEGLContext::swapBuffers: eglError: %d, this: %p \n", QWindowsEGLStaticContext::libEGL.eglGetError(), this);
+ if (!ok) {
+ err = QWindowsEGLStaticContext::libEGL.eglGetError();
+ if (err == EGL_CONTEXT_LOST) {
+ m_eglContext = EGL_NO_CONTEXT;
+ qCDebug(lcQpaGl) << "Got EGL context lost in eglSwapBuffers()";
+ } else {
+ qWarning("%s: Failed to swap buffers. eglError: %d, this: %p", __FUNCTION__, err, this);
+ }
+ }
}
QFunctionPointer QWindowsEGLContext::getProcAddress(const QByteArray &procName)
diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
index 3b27964b0e..8a2fbe1f6d 100644
--- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
+++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
@@ -40,11 +40,13 @@
#include <QtGui/QFont>
#include <QtGui/QGuiApplication>
+#include <QtGui/private/qhighdpiscaling_p.h>
#include <QtCore/qmath.h>
#include <QtCore/QDebug>
#include <QtCore/QtEndian>
#include <QtCore/QThreadStorage>
+#include <QtCore/private/qsystemlibrary_p.h>
#include <wchar.h>
@@ -59,6 +61,38 @@
QT_BEGIN_NAMESPACE
+#ifndef QT_NO_DIRECTWRITE
+// ### fixme: Consider direct linking of dwrite.dll once Windows Vista pre SP2 is dropped (QTBUG-49711)
+
+typedef HRESULT (WINAPI *DWriteCreateFactoryType)(DWRITE_FACTORY_TYPE, const IID &, IUnknown **);
+
+static inline DWriteCreateFactoryType resolveDWriteCreateFactory()
+{
+ if (QSysInfo::windowsVersion() < QSysInfo::WV_VISTA)
+ return Q_NULLPTR;
+ QSystemLibrary library(QStringLiteral("dwrite"));
+ QFunctionPointer result = library.resolve("DWriteCreateFactory");
+ if (Q_UNLIKELY(!result)) {
+ qWarning("Unable to load dwrite.dll");
+ return Q_NULLPTR;
+ }
+ return reinterpret_cast<DWriteCreateFactoryType>(result);
+}
+
+static IDWriteFactory *createDirectWriteFactory()
+{
+ static const DWriteCreateFactoryType dWriteCreateFactory = resolveDWriteCreateFactory();
+ if (!dWriteCreateFactory)
+ return Q_NULLPTR;
+ IUnknown *result = Q_NULLPTR;
+ if (FAILED(dWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), &result))) {
+ qErrnoWarning("DWriteCreateFactory failed");
+ return Q_NULLPTR;
+ }
+ return reinterpret_cast<IDWriteFactory *>(result);
+}
+#endif // !QT_NO_DIRECTWRITE
+
// Helper classes for creating font engines directly from font data
namespace {
@@ -465,14 +499,9 @@ namespace {
class CustomFontFileLoader
{
public:
- CustomFontFileLoader() : m_directWriteFactory(0), m_directWriteFontFileLoader(0)
+ CustomFontFileLoader() : m_directWriteFactory(createDirectWriteFactory()), m_directWriteFontFileLoader(0)
{
- HRESULT hres = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED,
- __uuidof(IDWriteFactory),
- reinterpret_cast<IUnknown **>(&m_directWriteFactory));
- if (FAILED(hres)) {
- qErrnoWarning(hres, "%s: DWriteCreateFactory failed.", __FUNCTION__);
- } else {
+ if (m_directWriteFactory) {
m_directWriteFontFileLoader = new DirectWriteFontFileLoader();
m_directWriteFactory->RegisterFontFileLoader(m_directWriteFontFileLoader);
}
@@ -570,15 +599,9 @@ qreal QWindowsFontDatabase::fontSmoothingGamma()
static inline bool initDirectWrite(QWindowsFontEngineData *d)
{
if (!d->directWriteFactory) {
- const HRESULT hr = DWriteCreateFactory(
- DWRITE_FACTORY_TYPE_SHARED,
- __uuidof(IDWriteFactory),
- reinterpret_cast<IUnknown **>(&d->directWriteFactory)
- );
- if (FAILED(hr)) {
- qErrnoWarning("%s: DWriteCreateFactory failed", __FUNCTION__);
+ d->directWriteFactory = createDirectWriteFactory();
+ if (!d->directWriteFactory)
return false;
- }
}
if (!d->directWriteGdiInterop) {
const HRESULT hr = d->directWriteFactory->GetGdiInterop(&d->directWriteGdiInterop);
@@ -606,6 +629,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);
@@ -617,6 +641,7 @@ QDebug operator<<(QDebug d, const QFontDef &def)
<< def.hintingPreference;
return d;
}
+#endif // !QT_NO_DEBUG_STREAM
static inline QFontDatabase::WritingSystem writingSystemFromCharSet(uchar charSet)
{
@@ -1098,8 +1123,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;
@@ -1211,11 +1239,13 @@ QT_WARNING_POP
fontFile->Release();
- fontEngine = new QWindowsFontEngineDirectWrite(directWriteFontFace, pixelSize,
+ fontEngine = new QWindowsFontEngineDirectWrite(directWriteFontFace,
+ pixelSize,
fontEngineData);
// Get font family from font data
fontEngine->fontDef.family = font.familyName();
+ fontEngine->fontDef.hintingPreference = hintingPreference;
directWriteFontFace->Release();
}
@@ -1702,7 +1732,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 795554698c..684c44acf2 100644
--- a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp
+++ b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp
@@ -194,7 +194,14 @@ typedef struct {
quint16 stringOffset;
} NAME_RECORD;
-static QString fontNameFromTTFile(const QString &filename)
+typedef struct {
+ quint32 tag;
+ quint16 majorVersion;
+ quint16 minorVersion;
+ quint32 numFonts;
+} TTC_TABLE_HEADER;
+
+static QString fontNameFromTTFile(const QString &filename, int startPos = 0)
{
QFile f(filename);
QString retVal;
@@ -202,6 +209,7 @@ static QString fontNameFromTTFile(const QString &filename)
qint64 bytesToRead;
if (f.open(QIODevice::ReadOnly)) {
+ f.seek(startPos);
OFFSET_TABLE ttOffsetTable;
bytesToRead = sizeof(OFFSET_TABLE);
bytesRead = f.read((char*)&ttOffsetTable, bytesToRead);
@@ -282,6 +290,37 @@ static QString fontNameFromTTFile(const QString &filename)
return retVal;
}
+static QStringList fontNamesFromTTCFile(const QString &filename)
+{
+ QFile f(filename);
+ QStringList retVal;
+ qint64 bytesRead;
+ qint64 bytesToRead;
+
+ if (f.open(QIODevice::ReadOnly)) {
+ TTC_TABLE_HEADER ttcTableHeader;
+ bytesToRead = sizeof(TTC_TABLE_HEADER);
+ bytesRead = f.read((char*)&ttcTableHeader, bytesToRead);
+ if (bytesToRead != bytesRead)
+ return retVal;
+ ttcTableHeader.majorVersion = qFromBigEndian(ttcTableHeader.majorVersion);
+ ttcTableHeader.minorVersion = qFromBigEndian(ttcTableHeader.minorVersion);
+ ttcTableHeader.numFonts = qFromBigEndian(ttcTableHeader.numFonts);
+
+ if (ttcTableHeader.majorVersion < 1 || ttcTableHeader.majorVersion > 2)
+ return retVal;
+ QVarLengthArray<quint32> offsetTable(ttcTableHeader.numFonts);
+ bytesToRead = sizeof(quint32) * ttcTableHeader.numFonts;
+ bytesRead = f.read((char*)offsetTable.data(), bytesToRead);
+ if (bytesToRead != bytesRead)
+ return retVal;
+ f.close();
+ for (int i = 0; i < (int)ttcTableHeader.numFonts; ++i)
+ retVal << fontNameFromTTFile(filename, qFromBigEndian(offsetTable[i]));
+ }
+ return retVal;
+}
+
static inline QString fontSettingsOrganization() { return QStringLiteral("Qt-Project"); }
static inline QString fontSettingsApplication() { return QStringLiteral("Qtbase"); }
static inline QString fontSettingsGroup() { return QStringLiteral("CEFontCache"); }
@@ -308,20 +347,28 @@ static QString findFontFile(const QString &faceName)
//empty the cache first, as it seems that it is dirty
settings.remove(QString());
- QDirIterator it(QStringLiteral("/Windows"), QStringList(QStringLiteral("*.ttf")), QDir::Files | QDir::Hidden | QDir::System);
-
+ QDirIterator it(QStringLiteral("/Windows"), QStringList() << QStringLiteral("*.ttf") << QStringLiteral("*.ttc"), QDir::Files | QDir::Hidden | QDir::System);
+ const QLatin1Char lowerF('f');
+ const QLatin1Char upperF('F');
while (it.hasNext()) {
const QString fontFile = it.next();
- const QString fontName = fontNameFromTTFile(fontFile);
- if (fontName.isEmpty())
- continue;
- fontCache.insert(fontName, fontFile);
- settings.setValue(fontName, fontFile);
-
- if (localizedName(fontName)) {
- QString englishFontName = getEnglishName(fontName);
- fontCache.insert(englishFontName, fontFile);
- settings.setValue(englishFontName, fontFile);
+ QStringList fontNames;
+ const QChar c = fontFile[fontFile.size() - 1];
+ if (c == lowerF || c == upperF)
+ fontNames << fontNameFromTTFile(fontFile);
+ else
+ fontNames << fontNamesFromTTCFile(fontFile);
+ foreach (const QString fontName, fontNames) {
+ if (fontName.isEmpty())
+ continue;
+ fontCache.insert(fontName, fontFile);
+ settings.setValue(fontName, fontFile);
+
+ if (localizedName(fontName)) {
+ QString englishFontName = getEnglishName(fontName);
+ fontCache.insert(englishFontName, fontFile);
+ settings.setValue(englishFontName, fontFile);
+ }
}
}
settings.endGroup();
@@ -355,7 +402,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);
@@ -677,7 +724,7 @@ QStringList QWindowsFontDatabaseFT::fallbacksForFamily(const QString &family, QF
result.append(QWindowsFontDatabase::extraTryFontsForFamily(family));
- result.append(QPlatformFontDatabase::fallbacksForFamily(family, style, styleHint, script));
+ result.append(QBasicFontDatabase::fallbacksForFamily(family, style, styleHint, script));
qCDebug(lcQpaFonts) << __FUNCTION__ << family << style << styleHint
<< script << result;
diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.h b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.h
index ad5c005ffa..f65dc38801 100644
--- a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.h
+++ b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.h
@@ -43,12 +43,15 @@ QT_BEGIN_NAMESPACE
class QWindowsFontDatabaseFT : public QBasicFontDatabase
{
public:
- void populateFontDatabase();
+ void populateFontDatabase() Q_DECL_OVERRIDE;
void populateFamily(const QString &familyName) Q_DECL_OVERRIDE;
- QFontEngine *fontEngine(const QFontDef &fontDef, void *handle);
- QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference);
+ QFontEngine *fontEngine(const QFontDef &fontDef, void *handle) Q_DECL_OVERRIDE;
+ QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize,
+ QFont::HintingPreference hintingPreference) Q_DECL_OVERRIDE;
- QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const;
+ QStringList fallbacksForFamily(const QString &family, QFont::Style style,
+ QFont::StyleHint styleHint,
+ QChar::Script script) const Q_DECL_OVERRIDE;
QString fontDir() const Q_DECL_OVERRIDE;
QFont defaultFont() const Q_DECL_OVERRIDE;
diff --git a/src/plugins/platforms/windows/qwindowsfontengine.cpp b/src/plugins/platforms/windows/qwindowsfontengine.cpp
index 3685197430..30417f7cee 100644
--- a/src/plugins/platforms/windows/qwindowsfontengine.cpp
+++ b/src/plugins/platforms/windows/qwindowsfontengine.cpp
@@ -1357,6 +1357,12 @@ QFontEngine *QWindowsMultiFontEngine::loadEngine(int at)
QWindowsFontEngineDirectWrite *fedw = new QWindowsFontEngineDirectWrite(directWriteFontFace,
fontEngine->fontDef.pixelSize,
data);
+ if (fontEngine->fontDef.weight > QFont::Normal)
+ fedw->fontDef.weight = fontEngine->fontDef.weight;
+ if (fontEngine->fontDef.style > QFont::StyleNormal)
+ fedw->fontDef.style = fontEngine->fontDef.style;
+ fedw->fontDef.family = fam;
+ fedw->fontDef.hintingPreference = fontEngine->fontDef.hintingPreference;
return fedw;
} else {
qErrnoWarning("%s: CreateFontFace failed", __FUNCTION__);
@@ -1368,7 +1374,14 @@ QFontEngine *QWindowsMultiFontEngine::loadEngine(int at)
// Get here if original font is not DirectWrite or DirectWrite creation failed for some
// reason
- return new QWindowsFontEngine(fam, lf, data);
+ QFontEngine *fe = new QWindowsFontEngine(fam, lf, data);
+ if (fontEngine->fontDef.weight > QFont::Normal)
+ fe->fontDef.weight = fontEngine->fontDef.weight;
+ if (fontEngine->fontDef.style > QFont::StyleNormal)
+ fe->fontDef.style = fontEngine->fontDef.style;
+ fe->fontDef.family = fam;
+ fe->fontDef.hintingPreference = fontEngine->fontDef.hintingPreference;
+ return fe;
}
bool QWindowsFontEngine::supportsTransformation(const QTransform &transform) const
diff --git a/src/plugins/platforms/windows/qwindowsfontengine.h b/src/plugins/platforms/windows/qwindowsfontengine.h
index 409b44264e..5317368455 100644
--- a/src/plugins/platforms/windows/qwindowsfontengine.h
+++ b/src/plugins/platforms/windows/qwindowsfontengine.h
@@ -84,7 +84,7 @@ public:
void addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs, QPainterPath *path, QTextItem::RenderFlags flags) Q_DECL_OVERRIDE;
virtual void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs,
- QPainterPath *path, QTextItem::RenderFlags flags);
+ QPainterPath *path, QTextItem::RenderFlags flags) Q_DECL_OVERRIDE;
HGDIOBJ selectDesignFont() const;
diff --git a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp
index 75449e22ed..a50ee60975 100644
--- a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp
+++ b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp
@@ -50,6 +50,7 @@
#include <QtCore/QtEndian>
#include <QtCore/QVarLengthArray>
#include <private/qstringiterator_p.h>
+#include <QtCore/private/qsystemlibrary_p.h>
#include <dwrite.h>
#include <d2d1.h>
@@ -196,8 +197,8 @@ namespace {
*/
QWindowsFontEngineDirectWrite::QWindowsFontEngineDirectWrite(IDWriteFontFace *directWriteFontFace,
- qreal pixelSize,
- const QSharedPointer<QWindowsFontEngineData> &d)
+ qreal pixelSize,
+ const QSharedPointer<QWindowsFontEngineData> &d)
: QFontEngine(DirectWrite)
, m_fontEngineData(d)
, m_directWriteFontFace(directWriteFontFace)
@@ -485,9 +486,9 @@ qreal QWindowsFontEngineDirectWrite::maxCharWidth() const
return 0;
}
-QImage QWindowsFontEngineDirectWrite::alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition)
+QImage QWindowsFontEngineDirectWrite::alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &t)
{
- QImage im = imageForGlyph(glyph, subPixelPosition, 0, QTransform());
+ QImage im = alphaRGBMapForGlyph(glyph, subPixelPosition, t);
QImage alphaMap(im.width(), im.height(), QImage::Format_Alpha8);
@@ -504,6 +505,11 @@ QImage QWindowsFontEngineDirectWrite::alphaMapForGlyph(glyph_t glyph, QFixed sub
return alphaMap;
}
+QImage QWindowsFontEngineDirectWrite::alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition)
+{
+ return alphaMapForGlyph(glyph, subPixelPosition, QTransform());
+}
+
bool QWindowsFontEngineDirectWrite::supportsSubPixelPositions() const
{
return true;
@@ -547,12 +553,17 @@ QImage QWindowsFontEngineDirectWrite::imageForGlyph(glyph_t t,
transform.m21 = xform.m21();
transform.m22 = xform.m22();
+ DWRITE_RENDERING_MODE renderMode =
+ fontDef.hintingPreference == QFont::PreferNoHinting
+ ? DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC
+ : DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL;
+
IDWriteGlyphRunAnalysis *glyphAnalysis = NULL;
HRESULT hr = m_fontEngineData->directWriteFactory->CreateGlyphRunAnalysis(
&glyphRun,
1.0f,
&transform,
- DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC,
+ renderMode,
DWRITE_MEASURING_MODE_NATURAL,
0.0, 0.0,
&glyphAnalysis
@@ -626,7 +637,8 @@ QImage QWindowsFontEngineDirectWrite::alphaRGBMapForGlyph(glyph_t t,
QFontEngine *QWindowsFontEngineDirectWrite::cloneWithSize(qreal pixelSize) const
{
QFontEngine *fontEngine = new QWindowsFontEngineDirectWrite(m_directWriteFontFace,
- pixelSize, m_fontEngineData);
+ pixelSize,
+ m_fontEngineData);
fontEngine->fontDef = fontDef;
fontEngine->fontDef.pixelSize = pixelSize;
@@ -634,6 +646,16 @@ QFontEngine *QWindowsFontEngineDirectWrite::cloneWithSize(qreal pixelSize) const
return fontEngine;
}
+// Dynamically resolve GetUserDefaultLocaleName, which is available from Windows
+// Vista onwards. ### fixme 5.7: Consider reverting to direct linking.
+typedef int (WINAPI *GetUserDefaultLocaleNamePtr)(LPWSTR, int);
+
+static inline GetUserDefaultLocaleNamePtr resolveGetUserDefaultLocaleName()
+{
+ QSystemLibrary library(QStringLiteral("kernel32"));
+ return (GetUserDefaultLocaleNamePtr)library.resolve("GetUserDefaultLocaleName");
+}
+
void QWindowsFontEngineDirectWrite::initFontInfo(const QFontDef &request,
int dpi, IDWriteFont *font)
{
@@ -652,7 +674,9 @@ void QWindowsFontEngineDirectWrite::initFontInfo(const QFontDef &request,
BOOL exists = false;
wchar_t localeName[LOCALE_NAME_MAX_LENGTH];
- int defaultLocaleSuccess = GetUserDefaultLocaleName(localeName, LOCALE_NAME_MAX_LENGTH);
+ static const GetUserDefaultLocaleNamePtr getUserDefaultLocaleName = resolveGetUserDefaultLocaleName();
+ const int defaultLocaleSuccess = getUserDefaultLocaleName
+ ? getUserDefaultLocaleName(localeName, LOCALE_NAME_MAX_LENGTH) : 0;
if (defaultLocaleSuccess)
hr = familyNames->FindLocaleName(localeName, &index, &exists);
@@ -703,9 +727,9 @@ QString QWindowsFontEngineDirectWrite::fontNameSubstitute(const QString &familyN
glyph_metrics_t QWindowsFontEngineDirectWrite::alphaMapBoundingBox(glyph_t glyph, QFixed pos, const QTransform &matrix, GlyphFormat format)
{
Q_UNUSED(pos);
- int margin = 0;
- if (format == QFontEngine::Format_A32 || format == QFontEngine::Format_ARGB)
- margin = glyphMargin(QFontEngine::Format_A32);
+ Q_UNUSED(format);
+
+ int margin = glyphMargin(QFontEngine::Format_A32);
glyph_metrics_t gm = QFontEngine::boundingBox(glyph, matrix);
gm.width += margin * 2;
gm.height += margin * 2;
diff --git a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h
index da772469e9..07e040ed33 100644
--- a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h
+++ b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h
@@ -61,34 +61,37 @@ public:
void initFontInfo(const QFontDef &request, int dpi, IDWriteFont *font);
- QFixed lineThickness() const;
- QFixed underlinePosition() const;
- bool getSfntTableData(uint tag, uchar *buffer, uint *length) const;
- QFixed emSquareSize() const;
+ QFixed lineThickness() const Q_DECL_OVERRIDE;
+ QFixed underlinePosition() const Q_DECL_OVERRIDE;
+ bool getSfntTableData(uint tag, uchar *buffer, uint *length) const Q_DECL_OVERRIDE;
+ QFixed emSquareSize() const Q_DECL_OVERRIDE;
glyph_t glyphIndex(uint ucs4) const Q_DECL_OVERRIDE;
- bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, ShaperFlags flags) const;
- void recalcAdvances(QGlyphLayout *glyphs, ShaperFlags) const;
+ bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs,
+ ShaperFlags flags) const Q_DECL_OVERRIDE;
+ void recalcAdvances(QGlyphLayout *glyphs, ShaperFlags) const Q_DECL_OVERRIDE;
void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs,
- QPainterPath *path, QTextItem::RenderFlags flags);
+ QPainterPath *path, QTextItem::RenderFlags flags) Q_DECL_OVERRIDE;
- glyph_metrics_t boundingBox(const QGlyphLayout &glyphs);
- glyph_metrics_t boundingBox(glyph_t g);
- glyph_metrics_t alphaMapBoundingBox(glyph_t glyph, QFixed, const QTransform &matrix, GlyphFormat);
+ glyph_metrics_t boundingBox(const QGlyphLayout &glyphs) Q_DECL_OVERRIDE;
+ glyph_metrics_t boundingBox(glyph_t g) Q_DECL_OVERRIDE;
+ glyph_metrics_t alphaMapBoundingBox(glyph_t glyph, QFixed,
+ const QTransform &matrix, GlyphFormat) Q_DECL_OVERRIDE;
- QFixed ascent() const;
- QFixed descent() const;
- QFixed leading() const;
- QFixed xHeight() const;
- qreal maxCharWidth() const;
+ QFixed ascent() const Q_DECL_OVERRIDE;
+ QFixed descent() const Q_DECL_OVERRIDE;
+ QFixed leading() const Q_DECL_OVERRIDE;
+ QFixed xHeight() const Q_DECL_OVERRIDE;
+ qreal maxCharWidth() const Q_DECL_OVERRIDE;
- bool supportsSubPixelPositions() const;
+ bool supportsSubPixelPositions() const Q_DECL_OVERRIDE;
- QImage alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition);
- QImage alphaRGBMapForGlyph(glyph_t t, QFixed subPixelPosition, const QTransform &xform);
+ QImage alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition) Q_DECL_OVERRIDE;
+ QImage alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &t) Q_DECL_OVERRIDE;
+ QImage alphaRGBMapForGlyph(glyph_t t, QFixed subPixelPosition, const QTransform &xform) Q_DECL_OVERRIDE;
- QFontEngine *cloneWithSize(qreal pixelSize) const;
+ QFontEngine *cloneWithSize(qreal pixelSize) const Q_DECL_OVERRIDE;
const QSharedPointer<QWindowsFontEngineData> &fontEngineData() const { return m_fontEngineData; }
diff --git a/src/plugins/platforms/windows/qwindowsglcontext.cpp b/src/plugins/platforms/windows/qwindowsglcontext.cpp
index a7c14ed2ac..8d33e2f0db 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,
@@ -436,7 +463,7 @@ static int choosePixelFormat(HDC hdc, const QSurfaceFormat &format,
PIXELFORMATDESCRIPTOR *obtainedPfd)
{
if (QOpenGLStaticContext::opengl32.moduleIsNotOpengl32()) {
- qWarning("%s: Attempted to use GDI functions with a non-opengl32.dll library", Q_FUNC_INFO);
+ qWarning("Attempted to use GDI functions with a non-opengl32.dll library");
return 0;
}
@@ -856,16 +883,11 @@ QWindowsOpenGLContextFormat QWindowsOpenGLContextFormat::current()
{
QWindowsOpenGLContextFormat result;
const QByteArray version = QOpenGLStaticContext::getGlString(GL_VERSION);
- const int majorDot = version.indexOf('.');
- if (majorDot != -1) {
- int minorDot = version.indexOf('.', majorDot + 1);
- if (minorDot == -1)
- minorDot = version.size();
- result.version = (version.mid(0, majorDot).toInt() << 8)
- + version.mid(majorDot + 1, minorDot - majorDot - 1).toInt();
- } else {
+ int major, minor;
+ if (QPlatformOpenGLContext::parseOpenGLVersion(version, major, minor))
+ result.version = (major << 8) + minor;
+ else
result.version = 0x0200;
- }
result.profile = QSurfaceFormat::NoProfile;
if (result.version < 0x0300) {
result.options |= QSurfaceFormat::DeprecatedFunctions;
@@ -905,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.
@@ -1005,7 +1018,7 @@ QByteArray QOpenGLStaticContext::getGlString(unsigned int which)
QOpenGLStaticContext *QOpenGLStaticContext::create(bool softwareRendering)
{
if (!opengl32.init(softwareRendering)) {
- qWarning("%s: Failed to load and resolve WGL/OpenGL functions", Q_FUNC_INFO);
+ qWarning("Failed to load and resolve WGL/OpenGL functions");
return 0;
}
@@ -1018,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/qwindowsguieventdispatcher.cpp b/src/plugins/platforms/windows/qwindowsguieventdispatcher.cpp
deleted file mode 100644
index 0bfa0239aa..0000000000
--- a/src/plugins/platforms/windows/qwindowsguieventdispatcher.cpp
+++ /dev/null
@@ -1,201 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Samuel Gaist <samuel.gaist@edeltech.ch>
-** 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 "qwindowsguieventdispatcher.h"
-#include "qwindowscontext.h"
-
-#include <qpa/qwindowsysteminterface.h>
-
-#include <QtCore/QCoreApplication>
-#include <QtCore/QStack>
-#include <QtCore/QDebug>
-
-#include <windowsx.h>
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \class QWindowsGuiEventDispatcher
- \brief Event dispatcher for Windows
-
- Maintains a global stack storing the current event dispatcher and
- its processing flags for access from the Windows procedure
- qWindowsWndProc. Handling the Lighthouse gui events should be done
- from within the qWindowsWndProc to ensure correct processing of messages.
-
- \internal
- \ingroup qt-lighthouse-win
-*/
-
-QWindowsGuiEventDispatcher::QWindowsGuiEventDispatcher(QObject *parent) :
- QEventDispatcherWin32(parent), m_flags(0)
-{
- setObjectName(QStringLiteral("QWindowsGuiEventDispatcher"));
- createInternalHwnd(); // QTBUG-40881: Do not delay registering timers, etc. for QtMfc.
-}
-
-bool QWindowsGuiEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)
-{
- const QEventLoop::ProcessEventsFlags oldFlags = m_flags;
- m_flags = flags;
- if (QWindowsContext::verbose > 2 && lcQpaEvents().isDebugEnabled())
- qCDebug(lcQpaEvents) << '>' << __FUNCTION__ << objectName() << flags;
- const bool rc = QEventDispatcherWin32::processEvents(flags);
- if (QWindowsContext::verbose > 2 && lcQpaEvents().isDebugEnabled())
- qCDebug(lcQpaEvents) << '<' << __FUNCTION__ << "returns" << rc;
- m_flags = oldFlags;
- return rc;
-}
-
-void QWindowsGuiEventDispatcher::sendPostedEvents()
-{
- QEventDispatcherWin32::sendPostedEvents();
- QWindowSystemInterface::sendWindowSystemEvents(m_flags);
-}
-
-// Helpers for printing debug output for WM_* messages.
-struct MessageDebugEntry
-{
- UINT message;
- const char *description;
- bool interesting;
-};
-
-static const MessageDebugEntry
-messageDebugEntries[] = {
- {WM_CREATE, "WM_CREATE", true},
- {WM_PAINT, "WM_PAINT", true},
- {WM_CLOSE, "WM_CLOSE", true},
- {WM_DESTROY, "WM_DESTROY", true},
- {WM_MOVE, "WM_MOVE", true},
- {WM_SIZE, "WM_SIZE", true},
- {WM_MOUSEACTIVATE,"WM_MOUSEACTIVATE", true},
- {WM_CHILDACTIVATE, "WM_CHILDACTIVATE", true},
- {WM_PARENTNOTIFY, "WM_PARENTNOTIFY", true},
- {WM_ENTERIDLE, "WM_ENTERIDLE", false},
- {WM_GETICON, "WM_GETICON", false},
- {WM_KEYDOWN, "WM_KEYDOWN", true},
- {WM_SYSKEYDOWN, "WM_SYSKEYDOWN", true},
- {WM_SYSCOMMAND, "WM_SYSCOMMAND", true},
- {WM_KEYUP, "WM_KEYUP", true},
- {WM_SYSKEYUP, "WM_SYSKEYUP", true},
-#if defined(WM_APPCOMMAND)
- {WM_APPCOMMAND, "WM_APPCOMMAND", true},
-#endif
- {WM_IME_CHAR, "WM_IMECHAR", true},
- {WM_IME_KEYDOWN, "WM_IMECHAR", true},
- {WM_CANCELMODE, "WM_CANCELMODE", true},
- {WM_CHAR, "WM_CHAR", true},
- {WM_DEADCHAR, "WM_DEADCHAR", true},
- {WM_ACTIVATE, "WM_ACTIVATE", true},
- {WM_GETMINMAXINFO, "WM_GETMINMAXINFO", true},
- {WM_SETFOCUS, "WM_SETFOCUS", true},
- {WM_KILLFOCUS, "WM_KILLFOCUS", true},
- {WM_ENABLE, "WM_ENABLE", true},
- {WM_SHOWWINDOW, "WM_SHOWWINDOW", true},
- {WM_WINDOWPOSCHANGING, "WM_WINDOWPOSCHANGING", true},
- {WM_WINDOWPOSCHANGED, "WM_WINDOWPOSCHANGED", true},
- {WM_SETCURSOR, "WM_SETCURSOR", false},
- {WM_GETFONT, "WM_GETFONT", true},
- {WM_NCMOUSEMOVE, "WM_NCMOUSEMOVE", true},
- {WM_LBUTTONDOWN, "WM_LBUTTONDOWN", true},
- {WM_LBUTTONUP, "WM_LBUTTONUP", true},
- {WM_LBUTTONDBLCLK, "WM_LBUTTONDBLCLK", true},
- {WM_RBUTTONDOWN, "WM_RBUTTONDOWN", true},
- {WM_RBUTTONUP, "WM_RBUTTONUP", true},
- {WM_RBUTTONDBLCLK, "WM_RBUTTONDBLCLK", true},
- {WM_MBUTTONDOWN, "WM_MBUTTONDOWN", true},
- {WM_MBUTTONUP, "WM_MBUTTONUP", true},
- {WM_MBUTTONDBLCLK, "WM_MBUTTONDBLCLK", true},
- {WM_MOUSEWHEEL, "WM_MOUSEWHEEL", true},
- {WM_XBUTTONDOWN, "WM_XBUTTONDOWN", true},
- {WM_XBUTTONUP, "WM_XBUTTONUP", true},
- {WM_XBUTTONDBLCLK, "WM_XBUTTONDBLCLK", true},
- {WM_MOUSEHWHEEL, "WM_MOUSEHWHEEL", true},
- {WM_NCCREATE, "WM_NCCREATE", true},
- {WM_NCCALCSIZE, "WM_NCCALCSIZE", true},
- {WM_NCACTIVATE, "WM_NCACTIVATE", true},
- {WM_NCMOUSELEAVE, "WM_NCMOUSELEAVE", true},
- {WM_NCLBUTTONDOWN, "WM_NCLBUTTONDOWN", true},
- {WM_NCLBUTTONUP, "WM_NCLBUTTONUP", true},
- {WM_ACTIVATEAPP, "WM_ACTIVATEAPP", true},
- {WM_NCPAINT, "WM_NCPAINT", true},
- {WM_ERASEBKGND, "WM_ERASEBKGND", true},
- {WM_MOUSEMOVE, "WM_MOUSEMOVE", true},
- {WM_MOUSELEAVE, "WM_MOUSELEAVE", true},
- {WM_NCHITTEST, "WM_NCHITTEST", false},
- {WM_IME_SETCONTEXT, "WM_IME_SETCONTEXT", true},
- {WM_INPUTLANGCHANGE, "WM_INPUTLANGCHANGE", true},
- {WM_IME_NOTIFY, "WM_IME_NOTIFY", true},
-#if defined(WM_DWMNCRENDERINGCHANGED)
- {WM_DWMNCRENDERINGCHANGED, "WM_DWMNCRENDERINGCHANGED", true},
-#endif
- {WM_IME_SETCONTEXT, "WM_IME_SETCONTEXT", true},
- {WM_IME_NOTIFY, "WM_IME_NOTIFY", true},
- {WM_TOUCH, "WM_TOUCH", true},
- {WM_CHANGECBCHAIN, "WM_CHANGECBCHAIN", true},
- {WM_DRAWCLIPBOARD, "WM_DRAWCLIPBOARD", true},
- {WM_RENDERFORMAT, "WM_RENDERFORMAT", true},
- {WM_RENDERALLFORMATS, "WM_RENDERALLFORMATS", true},
- {WM_DESTROYCLIPBOARD, "WM_DESTROYCLIPBOARD", true},
- {WM_CAPTURECHANGED, "WM_CAPTURECHANGED", true},
- {WM_IME_STARTCOMPOSITION, "WM_IME_STARTCOMPOSITION", true},
- {WM_IME_COMPOSITION, "WM_IME_COMPOSITION", true},
- {WM_IME_ENDCOMPOSITION, "WM_IME_ENDCOMPOSITION", true},
- {WM_IME_NOTIFY, "WM_IME_NOTIFY", true},
- {WM_IME_REQUEST, "WM_IME_REQUEST", true},
-#if !defined(Q_OS_WINCE) && !defined(QT_NO_SESSIONMANAGER)
- {WM_QUERYENDSESSION, "WM_QUERYENDSESSION", true},
- {WM_ENDSESSION, "WM_ENDSESSION", true},
-#endif
- {WM_DISPLAYCHANGE, "WM_DISPLAYCHANGE", true},
- {WM_THEMECHANGED, "WM_THEMECHANGED", true}
-};
-
-static inline const MessageDebugEntry *messageDebugEntry(UINT msg)
-{
- for (size_t i = 0; i < sizeof(messageDebugEntries)/sizeof(MessageDebugEntry); i++)
- if (messageDebugEntries[i].message == msg)
- return messageDebugEntries + i;
- return 0;
-}
-
-const char *QWindowsGuiEventDispatcher::windowsMessageName(UINT msg)
-{
- if (const MessageDebugEntry *e = messageDebugEntry(msg))
- return e->description;
- return "Unknown";
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsguieventdispatcher.h b/src/plugins/platforms/windows/qwindowsguieventdispatcher.h
deleted file mode 100644
index 3389139461..0000000000
--- a/src/plugins/platforms/windows/qwindowsguieventdispatcher.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/****************************************************************************
-**
-** 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 QWINDOWSGUIEVENTDISPATCHER_H
-#define QWINDOWSGUIEVENTDISPATCHER_H
-
-#include "qtwindows_additional.h"
-
-#include <QtCore/private/qeventdispatcher_win_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QWindowsGuiEventDispatcher : public QEventDispatcherWin32
-{
- Q_OBJECT
-public:
- explicit QWindowsGuiEventDispatcher(QObject *parent = 0);
-
- static const char *windowsMessageName(UINT msg);
-
- bool QT_ENSURE_STACK_ALIGNED_FOR_SSE processEvents(QEventLoop::ProcessEventsFlags flags) Q_DECL_OVERRIDE;
- void sendPostedEvents() Q_DECL_OVERRIDE;
-
-private:
- QEventLoop::ProcessEventsFlags m_flags;
-};
-
-QT_END_NAMESPACE
-
-#endif // QWINDOWSGUIEVENTDISPATCHER_H
diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.cpp b/src/plugins/platforms/windows/qwindowsinputcontext.cpp
index 68e38dc4a6..56b5561756 100644
--- a/src/plugins/platforms/windows/qwindowsinputcontext.cpp
+++ b/src/plugins/platforms/windows/qwindowsinputcontext.cpp
@@ -36,7 +36,6 @@
#include "qwindowswindow.h"
#include "qwindowsintegration.h"
#include "qwindowsmousehandler.h"
-#include "qwindowsscaling.h"
#include <QtCore/QDebug>
#include <QtCore/QObject>
@@ -85,6 +84,18 @@ static inline void imeNotifyCancelComposition(HWND hwnd)
ImmReleaseContext(hwnd, himc);
}
+static inline LCID languageIdFromLocaleId(LCID localeId)
+{
+ return localeId & 0xFFFF;
+}
+
+static inline LCID currentInputLanguageId()
+{
+ return languageIdFromLocaleId(reinterpret_cast<quintptr>(GetKeyboardLayout(0)));
+}
+
+Q_CORE_EXPORT QLocale qt_localeFromLCID(LCID id); // from qlocale_win.cpp
+
/*!
\class QWindowsInputContext
\brief Windows Input context implementation
@@ -154,7 +165,9 @@ QWindowsInputContext::CompositionContext::CompositionContext() :
QWindowsInputContext::QWindowsInputContext() :
m_WM_MSIME_MOUSE(RegisterWindowMessage(L"MSIMEMouseOperation")),
- m_endCompositionRecursionGuard(false)
+ m_endCompositionRecursionGuard(false),
+ m_languageId(currentInputLanguageId()),
+ m_locale(qt_localeFromLCID(m_languageId))
{
connect(QGuiApplication::inputMethod(), &QInputMethod::cursorRectangleChanged,
this, &QWindowsInputContext::cursorRectChanged);
@@ -220,21 +233,24 @@ void QWindowsInputContext::updateEnabled()
const bool accepted = inputMethodAccepted();
if (QWindowsContext::verbose > 1)
qCDebug(lcQpaInputMethods) << __FUNCTION__ << window << "accepted=" << accepted;
- if (accepted) {
- // Re-enable IME by associating default context saved on first disabling.
- if (platformWindow->testFlag(QWindowsWindow::InputMethodDisabled)) {
- ImmAssociateContext(platformWindow->handle(), QWindowsInputContext::m_defaultContext);
- platformWindow->clearFlag(QWindowsWindow::InputMethodDisabled);
- }
- } else {
- // Disable IME by associating 0 context. Store context first time.
- if (!platformWindow->testFlag(QWindowsWindow::InputMethodDisabled)) {
- const HIMC oldImC = ImmAssociateContext(platformWindow->handle(), 0);
- platformWindow->setFlag(QWindowsWindow::InputMethodDisabled);
- if (!QWindowsInputContext::m_defaultContext && oldImC)
- QWindowsInputContext::m_defaultContext = oldImC;
- }
- }
+ QWindowsInputContext::setWindowsImeEnabled(platformWindow, accepted);
+ }
+}
+
+void QWindowsInputContext::setWindowsImeEnabled(QWindowsWindow *platformWindow, bool enabled)
+{
+ if (!platformWindow || platformWindow->testFlag(QWindowsWindow::InputMethodDisabled) == !enabled)
+ return;
+ if (enabled) {
+ // Re-enable Windows IME by associating default context saved on first disabling.
+ ImmAssociateContext(platformWindow->handle(), QWindowsInputContext::m_defaultContext);
+ platformWindow->clearFlag(QWindowsWindow::InputMethodDisabled);
+ } else {
+ // Disable Windows IME by associating 0 context. Store context first time.
+ const HIMC oldImC = ImmAssociateContext(platformWindow->handle(), 0);
+ platformWindow->setFlag(QWindowsWindow::InputMethodDisabled);
+ if (!QWindowsInputContext::m_defaultContext && oldImC)
+ QWindowsInputContext::m_defaultContext = oldImC;
}
}
@@ -254,10 +270,9 @@ void QWindowsInputContext::cursorRectChanged()
if (!m_compositionContext.hwnd)
return;
const QInputMethod *inputMethod = QGuiApplication::inputMethod();
- const QRect cursorRectangleDip = inputMethod->cursorRectangle().toRect();
- if (!cursorRectangleDip.isValid())
+ const QRect cursorRectangle = inputMethod->cursorRectangle().toRect();
+ if (!cursorRectangle.isValid())
return;
- const QRect cursorRectangle = QWindowsScaling::mapToNative(cursorRectangleDip);
qCDebug(lcQpaInputMethods) << __FUNCTION__<< cursorRectangle;
@@ -308,11 +323,6 @@ void QWindowsInputContext::invokeAction(QInputMethod::Action action, int cursorP
ImmReleaseContext(m_compositionContext.hwnd, himc);
}
-QWindowsInputContext *QWindowsInputContext::instance()
-{
- return static_cast<QWindowsInputContext *>(QWindowsIntegration::instance()->inputContext());
-}
-
static inline QString getCompositionString(HIMC himc, DWORD dwIndex)
{
enum { bufferSize = 256 };
@@ -375,7 +385,7 @@ bool QWindowsInputContext::startComposition(HWND hwnd)
QWindow *window = QGuiApplication::focusWindow();
if (!window)
return false;
- qCDebug(lcQpaInputMethods) << __FUNCTION__ << fo << window;
+ qCDebug(lcQpaInputMethods) << __FUNCTION__ << fo << window << "language=" << m_languageId;
if (!fo || QWindowsWindow::handleOf(window) != hwnd)
return false;
initContext(hwnd, fo);
@@ -474,7 +484,8 @@ bool QWindowsInputContext::composition(HWND hwnd, LPARAM lParamIn)
if (lParam & GCS_RESULTSTR) {
// A fixed result, return the converted string
event->setCommitString(getCompositionString(himc, GCS_RESULTSTR));
- endContextComposition();
+ if (!(lParam & GCS_DELTASTART))
+ endContextComposition();
}
const bool result = QCoreApplication::sendEvent(m_compositionContext.focusObject, event.data());
qCDebug(lcQpaInputMethods) << '<' << __FUNCTION__ << "sending markup="
@@ -559,6 +570,21 @@ bool QWindowsInputContext::handleIME_Request(WPARAM wParam,
return false;
}
+void QWindowsInputContext::handleInputLanguageChanged(WPARAM wparam, LPARAM lparam)
+{
+ const LCID newLanguageId = languageIdFromLocaleId(lparam);
+ if (newLanguageId == m_languageId)
+ return;
+ const LCID oldLanguageId = m_languageId;
+ m_languageId = newLanguageId;
+ m_locale = qt_localeFromLCID(m_languageId);
+ emitLocaleChanged();
+
+ qCDebug(lcQpaInputMethods) << __FUNCTION__ << hex << showbase
+ << oldLanguageId << "->" << newLanguageId << "Character set:"
+ << DWORD(wparam) << dec << noshowbase << m_locale;
+}
+
/*!
\brief Determines the string for reconversion with selection.
diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.h b/src/plugins/platforms/windows/qwindowsinputcontext.h
index 110986c20c..636d481e70 100644
--- a/src/plugins/platforms/windows/qwindowsinputcontext.h
+++ b/src/plugins/platforms/windows/qwindowsinputcontext.h
@@ -36,12 +36,14 @@
#include "qtwindows_additional.h"
+#include <QtCore/QLocale>
#include <QtCore/QPointer>
#include <qpa/qplatforminputcontext.h>
QT_BEGIN_NAMESPACE
class QInputMethodEvent;
+class QWindowsWindow;
class QWindowsInputContext : public QPlatformInputContext
{
@@ -62,14 +64,16 @@ public:
explicit QWindowsInputContext();
~QWindowsInputContext();
+ static void setWindowsImeEnabled(QWindowsWindow *platformWindow, bool enabled);
+
bool hasCapability(Capability capability) const Q_DECL_OVERRIDE;
+ QLocale locale() const Q_DECL_OVERRIDE { return m_locale; }
+
void reset() Q_DECL_OVERRIDE;
void update(Qt::InputMethodQueries) Q_DECL_OVERRIDE;
void invokeAction(QInputMethod::Action, int cursorPosition) Q_DECL_OVERRIDE;
void setFocusObject(QObject *object) Q_DECL_OVERRIDE;
- static QWindowsInputContext *instance();
-
bool startComposition(HWND hwnd);
bool composition(HWND hwnd, LPARAM lParam);
bool endComposition(HWND hwnd);
@@ -78,6 +82,7 @@ public:
int reconvertString(RECONVERTSTRING *reconv);
bool handleIME_Request(WPARAM wparam, LPARAM lparam, LRESULT *result);
+ void handleInputLanguageChanged(WPARAM wparam, LPARAM lparam);
private slots:
void cursorRectChanged();
@@ -93,6 +98,8 @@ private:
static HIMC m_defaultContext;
CompositionContext m_compositionContext;
bool m_endCompositionRecursionGuard;
+ LCID m_languageId;
+ QLocale m_locale;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp
index 089c3cd0fe..bd2014b8f2 100644
--- a/src/plugins/platforms/windows/qwindowsintegration.cpp
+++ b/src/plugins/platforms/windows/qwindowsintegration.cpp
@@ -33,7 +33,6 @@
****************************************************************************/
#include "qwindowsintegration.h"
-#include "qwindowsscaling.h"
#include "qwindowswindow.h"
#include "qwindowscontext.h"
#include "qwindowsopenglcontext.h"
@@ -45,7 +44,6 @@
# include "qwindowsfontdatabase_ft.h"
#endif
#include "qwindowsfontdatabase.h"
-#include "qwindowsguieventdispatcher.h"
#ifndef QT_NO_CLIPBOARD
# include "qwindowsclipboard.h"
# ifndef QT_NO_DRAGANDDROP
@@ -64,9 +62,11 @@
# include "qwindowssessionmanager.h"
#endif
#include <QtGui/private/qguiapplication_p.h>
+#include <QtGui/private/qhighdpiscaling_p.h>
#include <QtGui/qpa/qplatforminputcontextfactory_p.h>
-#include <QtCore/private/qeventdispatcher_win_p.h>
+#include <QtPlatformSupport/private/qwindowsguieventdispatcher_p.h>
+
#include <QtCore/QDebug>
#include <QtCore/QVariant>
@@ -223,12 +223,9 @@ QWindowsIntegrationPrivate::QWindowsIntegrationPrivate(const QStringList &paramL
m_context.setProcessDpiAwareness(dpiAwareness);
dpiAwarenessSet = true;
}
- // Determine suitable scale factor, don't mix Windows and Qt scaling
- if (dpiAwareness != QtWindows::ProcessDpiUnaware)
- QWindowsScaling::setFactor(QWindowsScaling::determineUiScaleFactor());
qCDebug(lcQpaWindows)
- << __FUNCTION__ << "DpiAwareness=" << dpiAwareness <<",Scaling="
- << QWindowsScaling::factor();
+ << __FUNCTION__ << "DpiAwareness=" << dpiAwareness
+ << "effective process DPI awareness=" << QWindowsContext::processDpiAwareness();
m_context.initTouch(m_options);
}
@@ -258,10 +255,9 @@ QWindowsIntegration::~QWindowsIntegration()
void QWindowsIntegration::initialize()
{
- if (QPlatformInputContext *pluginContext = QPlatformInputContextFactory::create())
- d->m_inputContext.reset(pluginContext);
- else
- d->m_inputContext.reset(new QWindowsInputContext);
+ QString icStr = QPlatformInputContextFactory::requested();
+ icStr.isNull() ? d->m_inputContext.reset(new QWindowsInputContext)
+ : d->m_inputContext.reset(QPlatformInputContextFactory::create(icStr));
}
bool QWindowsIntegration::hasCapability(QPlatformIntegration::Capability cap) const
@@ -287,17 +283,19 @@ bool QWindowsIntegration::hasCapability(QPlatformIntegration::Capability cap) co
return true;
case AllGLFunctionsQueryable:
return true;
+ case SwitchableWidgetComposition:
+ return true;
default:
return QPlatformIntegration::hasCapability(cap);
}
return false;
}
-QWindowsWindowData QWindowsIntegration::createWindowData(QWindow *window) const
+QPlatformWindow *QWindowsIntegration::createPlatformWindow(QWindow *window) const
{
QWindowsWindowData requested;
requested.flags = window->flags();
- requested.geometry = QWindowsScaling::mapToNative(window->geometry());
+ requested.geometry = QHighDpi::toNativePixels(window->geometry(), window);
// Apply custom margins (see QWindowsWindow::setCustomMargins())).
const QVariant customMarginsV = window->property("_q_windowsCustomMargins");
if (customMarginsV.isValid())
@@ -312,22 +310,30 @@ QWindowsWindowData QWindowsIntegration::createWindowData(QWindow *window) const
<< "\n Obtained : " << obtained.geometry << " margins=" << obtained.frame
<< " handle=" << obtained.hwnd << ' ' << obtained.flags << '\n';
- if (obtained.hwnd) {
- if (requested.flags != obtained.flags)
- window->setFlags(obtained.flags);
- // Trigger geometry change signals of QWindow.
- if ((obtained.flags & Qt::Desktop) != Qt::Desktop && requested.geometry != obtained.geometry)
- QWindowSystemInterface::handleGeometryChange(window, QWindowsScaling::mapFromNative(obtained.geometry));
+ if (Q_UNLIKELY(!obtained.hwnd))
+ return Q_NULLPTR;
+
+ QWindowsWindow *result = createPlatformWindowHelper(window, obtained);
+ Q_ASSERT(result);
+
+ if (requested.flags != obtained.flags)
+ window->setFlags(obtained.flags);
+ // Trigger geometry/screen change signals of QWindow.
+ if ((obtained.flags & Qt::Desktop) != Qt::Desktop) {
+ if (requested.geometry != obtained.geometry)
+ QWindowSystemInterface::handleGeometryChange(window, obtained.geometry);
+ QPlatformScreen *screen = result->screenForGeometry(obtained.geometry);
+ if (screen && result->screen() != screen)
+ QWindowSystemInterface::handleWindowScreenChanged(window, screen->screen());
}
- return obtained;
+ return result;
}
-QPlatformWindow *QWindowsIntegration::createPlatformWindow(QWindow *window) const
+// Overridden to return a QWindowsDirect2DWindow in Direct2D plugin.
+QWindowsWindow *QWindowsIntegration::createPlatformWindowHelper(QWindow *window, const QWindowsWindowData &data) const
{
- QWindowsWindowData data = createWindowData(window);
- return data.hwnd ? new QWindowsWindow(window, data)
- : Q_NULLPTR;
+ return new QWindowsWindow(window, data);
}
#ifndef QT_NO_OPENGL
@@ -335,11 +341,18 @@ QPlatformWindow *QWindowsIntegration::createPlatformWindow(QWindow *window) cons
QWindowsStaticOpenGLContext *QWindowsStaticOpenGLContext::doCreate()
{
#if defined(QT_OPENGL_DYNAMIC)
+ const QWindowsOpenGLTester::Renderers supportedRenderers = QWindowsOpenGLTester::supportedRenderers();
+
QWindowsOpenGLTester::Renderer requestedRenderer = QWindowsOpenGLTester::requestedRenderer();
switch (requestedRenderer) {
case QWindowsOpenGLTester::DesktopGl:
- if (QWindowsStaticOpenGLContext *glCtx = QOpenGLStaticContext::create())
+ if (QWindowsStaticOpenGLContext *glCtx = QOpenGLStaticContext::create()) {
+ if ((supportedRenderers & QWindowsOpenGLTester::DisableRotationFlag)
+ && !QWindowsScreen::setOrientationPreference(Qt::LandscapeOrientation)) {
+ qCWarning(lcQpaGl, "Unable to disable rotation.");
+ }
return glCtx;
+ }
qCWarning(lcQpaGl, "System OpenGL failed. Falling back to Software OpenGL.");
return QOpenGLStaticContext::create(true);
// If ANGLE is requested, use it, don't try anything else.
@@ -360,10 +373,14 @@ QWindowsStaticOpenGLContext *QWindowsStaticOpenGLContext::doCreate()
break;
}
- const QWindowsOpenGLTester::Renderers supportedRenderers = QWindowsOpenGLTester::supportedRenderers();
if (supportedRenderers & QWindowsOpenGLTester::DesktopGl) {
- if (QWindowsStaticOpenGLContext *glCtx = QOpenGLStaticContext::create())
+ if (QWindowsStaticOpenGLContext *glCtx = QOpenGLStaticContext::create()) {
+ if ((supportedRenderers & QWindowsOpenGLTester::DisableRotationFlag)
+ && !QWindowsScreen::setOrientationPreference(Qt::LandscapeOrientation)) {
+ qCWarning(lcQpaGl, "Unable to disable rotation.");
+ }
return glCtx;
+ }
}
if (QWindowsOpenGLTester::Renderers glesRenderers = supportedRenderers & QWindowsOpenGLTester::GlesMask) {
if (QWindowsEGLStaticContext *eglCtx = QWindowsEGLStaticContext::create(glesRenderers))
diff --git a/src/plugins/platforms/windows/qwindowsintegration.h b/src/plugins/platforms/windows/qwindowsintegration.h
index fa5192ba03..da20d9261a 100644
--- a/src/plugins/platforms/windows/qwindowsintegration.h
+++ b/src/plugins/platforms/windows/qwindowsintegration.h
@@ -60,13 +60,12 @@ public:
explicit QWindowsIntegration(const QStringList &paramList);
virtual ~QWindowsIntegration();
- bool hasCapability(QPlatformIntegration::Capability cap) const;
+ bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE;
- QWindowsWindowData createWindowData(QWindow *window) const;
- QPlatformWindow *createPlatformWindow(QWindow *window) const;
+ QPlatformWindow *createPlatformWindow(QWindow *window) const Q_DECL_OVERRIDE;
#ifndef QT_NO_OPENGL
QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const Q_DECL_OVERRIDE;
- QOpenGLContext::OpenGLModuleType openGLModuleType();
+ QOpenGLContext::OpenGLModuleType openGLModuleType() Q_DECL_OVERRIDE;
static QWindowsStaticOpenGLContext *staticOpenGLContext();
#endif
QAbstractEventDispatcher *createEventDispatcher() const Q_DECL_OVERRIDE;
@@ -84,7 +83,7 @@ public:
QPlatformFontDatabase *fontDatabase() const Q_DECL_OVERRIDE;
QStringList themeNames() const Q_DECL_OVERRIDE;
QPlatformTheme *createPlatformTheme(const QString &name) const Q_DECL_OVERRIDE;
- QPlatformServices *services() const;
+ QPlatformServices *services() const Q_DECL_OVERRIDE;
QVariant styleHint(StyleHint hint) const Q_DECL_OVERRIDE;
Qt::KeyboardModifiers queryKeyboardModifiers() const Q_DECL_OVERRIDE;
@@ -101,6 +100,9 @@ public:
QPlatformSessionManager *createPlatformSessionManager(const QString &id, const QString &key) const Q_DECL_OVERRIDE;
#endif
+protected:
+ virtual QWindowsWindow *createPlatformWindowHelper(QWindow *window, const QWindowsWindowData &) const;
+
private:
QScopedPointer<QWindowsIntegrationPrivate> d;
diff --git a/src/plugins/platforms/windows/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp
index d47c7df9e0..c5dff60114 100644
--- a/src/plugins/platforms/windows/qwindowskeymapper.cpp
+++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp
@@ -33,15 +33,16 @@
#include "qwindowskeymapper.h"
#include "qwindowscontext.h"
+#include "qwindowsintegration.h"
#include "qwindowswindow.h"
-#include "qwindowsguieventdispatcher.h"
-#include "qwindowsscaling.h"
#include "qwindowsinputcontext.h"
#include <QtGui/QWindow>
#include <qpa/qwindowsysteminterface.h>
#include <private/qguiapplication_p.h>
+#include <private/qhighdpiscaling_p.h>
#include <QtGui/QKeyEvent>
+#include <QtPlatformSupport/private/qwindowsguieventdispatcher_p.h>
#if defined(WM_APPCOMMAND)
# ifndef FAPPCOMMAND_MOUSE
@@ -85,10 +86,15 @@ QT_BEGIN_NAMESPACE
The code originates from \c qkeymapper_win.cpp.
*/
+static void clearKeyRecorderOnApplicationInActive(Qt::ApplicationState state);
+
QWindowsKeyMapper::QWindowsKeyMapper()
: m_useRTLExtensions(false), m_keyGrabber(0)
{
memset(keyLayout, 0, sizeof(keyLayout));
+ QGuiApplication *app = static_cast<QGuiApplication *>(QGuiApplication::instance());
+ QObject::connect(app, &QGuiApplication::applicationStateChanged,
+ app, clearKeyRecorderOnApplicationInActive);
}
QWindowsKeyMapper::~QWindowsKeyMapper()
@@ -143,6 +149,12 @@ struct KeyRecorder
};
static KeyRecorder key_recorder;
+static void clearKeyRecorderOnApplicationInActive(Qt::ApplicationState state)
+{
+ if (state == Qt::ApplicationInactive)
+ key_recorder.clearKeys();
+}
+
KeyRecord *KeyRecorder::findKey(int code, bool remove)
{
KeyRecord *result = 0;
@@ -792,10 +804,12 @@ static void showSystemMenu(QWindow* w)
#undef enabled
#undef disabled
#endif // !Q_OS_WINCE
- const QPoint topLeft = topLevel->geometry().topLeft() * QWindowsScaling::factor();
+ const QPoint pos = QHighDpi::toNativePixels(topLevel->geometry().topLeft(), topLevel);
const int ret = TrackPopupMenuEx(menu,
TPM_LEFTALIGN | TPM_TOPALIGN | TPM_NONOTIFY | TPM_RETURNCMD,
- topLeft.x(), topLeft.y(), topLevelHwnd, 0);
+ pos.x(), pos.y(),
+ topLevelHwnd,
+ 0);
if (ret)
qWindowsWndProc(topLevelHwnd, WM_SYSCOMMAND, ret, 0);
}
@@ -1072,7 +1086,9 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, const MSG &ms
// results, if we map this virtual key-code directly (for eg '?' US layouts). So try
// to find the correct key using the current message parameters & keyboard state.
if (uch.isNull() && msgType == WM_IME_KEYDOWN) {
- if (!QWindowsInputContext::instance()->isComposing())
+ const QWindowsInputContext *windowsInputContext =
+ qobject_cast<const QWindowsInputContext *>(QWindowsIntegration::instance()->inputContext());
+ if (!(windowsInputContext && windowsInputContext->isComposing()))
vk_key = ImmGetVirtualKey((HWND)window->winId());
BYTE keyState[256];
wchar_t newKey[3] = {0};
diff --git a/src/plugins/platforms/windows/qwindowsmime.cpp b/src/plugins/platforms/windows/qwindowsmime.cpp
index 622352e987..171ace5c20 100644
--- a/src/plugins/platforms/windows/qwindowsmime.cpp
+++ b/src/plugins/platforms/windows/qwindowsmime.cpp
@@ -299,8 +299,6 @@ static bool qt_read_dibv5(QDataStream &s, QImage &image)
return true;
}
-//#define QMIME_DEBUG
-
// helpers for using global memory
static int getCf(const FORMATETC &formatetc)
@@ -380,6 +378,73 @@ static bool canGetData(int cf, IDataObject * pDataObj)
return true;
}
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug d, const FORMATETC &tc)
+{
+ QDebugStateSaver saver(d);
+ d.nospace();
+ d << "FORMATETC(cfFormat=" << tc.cfFormat << ' ';
+ switch (tc.cfFormat) {
+ case CF_TEXT:
+ d << "CF_TEXT";
+ break;
+ case CF_BITMAP:
+ d << "CF_BITMAP";
+ break;
+ case CF_TIFF:
+ d << "CF_TIFF";
+ break;
+ case CF_OEMTEXT:
+ d << "CF_OEMTEXT";
+ break;
+ case CF_DIB:
+ d << "CF_DIB";
+ break;
+ case CF_DIBV5:
+ d << "CF_DIBV5";
+ break;
+ case CF_UNICODETEXT:
+ d << "CF_UNICODETEXT";
+ break;
+#ifndef Q_OS_WINCE
+ case CF_ENHMETAFILE:
+ d << "CF_ENHMETAFILE";
+ break;
+#endif // !Q_OS_WINCE
+ default:
+ d << QWindowsMimeConverter::clipboardFormatName(tc.cfFormat);
+ break;
+ }
+ d << ", dwAspect=" << tc.dwAspect << ", lindex=" << tc.lindex
+ << ", tymed=" << tc.tymed << ", ptd=" << tc.ptd << ')';
+ return d;
+}
+
+QDebug operator<<(QDebug d, IDataObject *dataObj)
+{
+ QDebugStateSaver saver(d);
+ d.nospace();
+ d.noquote();
+ d << "IDataObject(";
+ if (dataObj) { // Output formats contained in IDataObject.
+ IEnumFORMATETC *enumFormatEtc;
+ if (SUCCEEDED(dataObj->EnumFormatEtc(DATADIR_GET, &enumFormatEtc)) && enumFormatEtc) {
+ FORMATETC formatEtc[1];
+ ULONG fetched;
+ if (SUCCEEDED(enumFormatEtc->Reset())) {
+ while (SUCCEEDED(enumFormatEtc->Next(1, formatEtc, &fetched)) && fetched)
+ d << formatEtc[0] << ',';
+ enumFormatEtc->Release();
+ }
+ }
+ } else {
+ d << '0';
+ }
+ d << ')';
+ return d;
+}
+#endif // !QT_NO_DEBUG_STREAM
+
/*!
\class QWindowsMime
\brief The QWindowsMime class maps open-standard MIME to Window Clipboard formats.
@@ -832,14 +897,14 @@ public:
QWindowsMimeHtml();
// for converting from Qt
- bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const;
- bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const;
- QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const;
+ bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const Q_DECL_OVERRIDE;
+ bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const Q_DECL_OVERRIDE;
+ QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const Q_DECL_OVERRIDE;
// for converting to Qt
- bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const;
- QVariant convertToMime(const QString &mime, IDataObject *pDataObj, QVariant::Type preferredType) const;
- QString mimeForFormat(const FORMATETC &formatetc) const;
+ bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const Q_DECL_OVERRIDE;
+ QVariant convertToMime(const QString &mime, IDataObject *pDataObj, QVariant::Type preferredType) const Q_DECL_OVERRIDE;
+ QString mimeForFormat(const FORMATETC &formatetc) const Q_DECL_OVERRIDE;
private:
int CF_HTML;
@@ -894,11 +959,7 @@ QVariant QWindowsMimeHtml::convertToMime(const QString &mime, IDataObject *pData
QVariant result;
if (canConvertToMime(mime, pDataObj)) {
QByteArray html = getData(CF_HTML, pDataObj);
-#ifdef QMIME_DEBUG
- qDebug("QWindowsMimeHtml::convertToMime");
- qDebug("raw :");
- qDebug(html);
-#endif
+ qCDebug(lcQpaMime) << __FUNCTION__ << "raw:" << html;
int start = html.indexOf("StartHTML:");
int end = html.indexOf("EndHTML:");
@@ -968,14 +1029,14 @@ class QWindowsMimeImage : public QWindowsMime
public:
QWindowsMimeImage();
// for converting from Qt
- bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const;
- bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const;
- QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const;
+ bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const Q_DECL_OVERRIDE;
+ bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const Q_DECL_OVERRIDE;
+ QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const Q_DECL_OVERRIDE;
// for converting to Qt
- bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const;
- QVariant convertToMime(const QString &mime, IDataObject *pDataObj, QVariant::Type preferredType) const;
- QString mimeForFormat(const FORMATETC &formatetc) const;
+ bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const Q_DECL_OVERRIDE;
+ QVariant convertToMime(const QString &mime, IDataObject *pDataObj, QVariant::Type preferredType) const Q_DECL_OVERRIDE;
+ QString mimeForFormat(const FORMATETC &formatetc) const Q_DECL_OVERRIDE;
private:
bool hasOriginalDIBV5(IDataObject *pDataObj) const;
UINT CF_PNG;
@@ -996,6 +1057,8 @@ QVector<FORMATETC> QWindowsMimeImage::formatsForMime(const QString &mimeType, co
formatetcs += setCf(CF_DIBV5);
formatetcs += setCf(CF_DIB);
}
+ if (!formatetcs.isEmpty())
+ qCDebug(lcQpaMime) << __FUNCTION__ << mimeType << formatetcs;
return formatetcs;
}
@@ -1120,14 +1183,14 @@ public:
QBuiltInMimes();
// for converting from Qt
- bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const;
- bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const;
- QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const;
+ bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const Q_DECL_OVERRIDE;
+ bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const Q_DECL_OVERRIDE;
+ QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const Q_DECL_OVERRIDE;
// for converting to Qt
- bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const;
- QVariant convertToMime(const QString &mime, IDataObject *pDataObj, QVariant::Type preferredType) const;
- QString mimeForFormat(const FORMATETC &formatetc) const;
+ bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const Q_DECL_OVERRIDE;
+ QVariant convertToMime(const QString &mime, IDataObject *pDataObj, QVariant::Type preferredType) const Q_DECL_OVERRIDE;
+ QString mimeForFormat(const FORMATETC &formatetc) const Q_DECL_OVERRIDE;
private:
QMap<int, QString> outFormats;
@@ -1216,9 +1279,7 @@ QVariant QBuiltInMimes::convertToMime(const QString &mimeType, IDataObject *pDat
if (canConvertToMime(mimeType, pDataObj)) {
QByteArray data = getData(inFormats.key(mimeType), pDataObj);
if (!data.isEmpty()) {
-#ifdef QMIME_DEBUG
- qDebug("QBuiltInMimes::convertToMime()");
-#endif
+ qCDebug(lcQpaMime) << __FUNCTION__;
if (mimeType == QLatin1String("text/html") && preferredType == QVariant::String) {
// text/html is in wide chars on windows (compatible with Mozilla)
val = QString::fromWCharArray((const wchar_t *)data.data());
@@ -1242,14 +1303,14 @@ public:
QLastResortMimes();
// for converting from Qt
- bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const;
- bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const;
- QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const;
+ bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const Q_DECL_OVERRIDE;
+ bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const Q_DECL_OVERRIDE;
+ QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const Q_DECL_OVERRIDE;
// for converting to Qt
- bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const;
- QVariant convertToMime(const QString &mime, IDataObject *pDataObj, QVariant::Type preferredType) const;
- QString mimeForFormat(const FORMATETC &formatetc) const;
+ bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const Q_DECL_OVERRIDE;
+ QVariant convertToMime(const QString &mime, IDataObject *pDataObj, QVariant::Type preferredType) const Q_DECL_OVERRIDE;
+ QString mimeForFormat(const FORMATETC &formatetc) const Q_DECL_OVERRIDE;
private:
QMap<int, QString> formats;
@@ -1326,6 +1387,8 @@ QVector<FORMATETC> QLastResortMimes::formatsForMime(const QString &mimeType, con
that->formats.insert(cf, mimeType);
formatetcs += setCf(cf);
}
+ if (!formatetcs.isEmpty())
+ qCDebug(lcQpaMime) << __FUNCTION__ << mimeType << formatetcs;
return formatetcs;
}
static const char x_qt_windows_mime[] = "application/x-qt-windows-mime;value=\"";
@@ -1400,11 +1463,8 @@ QString QLastResortMimes::mimeForFormat(const FORMATETC &formatetc) const
if (!format.isEmpty())
return format;
- wchar_t buffer[256];
- int len = GetClipboardFormatName(getCf(formatetc), buffer, 256);
-
- if (len) {
- QString clipFormat = QString::fromWCharArray(buffer, len);
+ const QString clipFormat = QWindowsMimeConverter::clipboardFormatName(getCf(formatetc));
+ if (!clipFormat.isEmpty()) {
#ifndef QT_NO_DRAGANDDROP
if (QInternalMimeData::canReadData(clipFormat))
format = clipFormat;
@@ -1470,15 +1530,12 @@ QStringList QWindowsMimeConverter::allMimesForFormats(IDataObject *pDataObj) con
if (hr == NOERROR) {
FORMATETC fmtetc;
while (S_OK == fmtenum->Next(1, &fmtetc, 0)) {
-#if defined(QMIME_DEBUG)
- wchar_t buf[256] = {0};
- GetClipboardFormatName(fmtetc.cfFormat, buf, 255);
- qDebug("CF = %d : %s", fmtetc.cfFormat, qPrintable(QString::fromWCharArray(buf)));
-#endif
for (int i= m_mimes.size() - 1; i >= 0; --i) {
QString format = m_mimes.at(i)->mimeForFormat(fmtetc);
if (!format.isEmpty() && !formats.contains(format)) {
formats += format;
+ if (QWindowsContext::verbose > 1 && lcQpaMime().isDebugEnabled())
+ qCDebug(lcQpaMime) << __FUNCTION__ << fmtetc << format;
}
}
// as documented in MSDN to avoid possible memleak
@@ -1494,6 +1551,7 @@ QStringList QWindowsMimeConverter::allMimesForFormats(IDataObject *pDataObj) con
QWindowsMime * QWindowsMimeConverter::converterFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const
{
ensureInitialized();
+ qCDebug(lcQpaMime) << __FUNCTION__ << formatetc;
for (int i = m_mimes.size()-1; i >= 0; --i) {
if (m_mimes.at(i)->canConvertFromMime(formatetc, mimeData))
return m_mimes.at(i);
@@ -1521,13 +1579,24 @@ QVector<FORMATETC> QWindowsMimeConverter::allFormatsForMime(const QMimeData *mim
void QWindowsMimeConverter::ensureInitialized() const
{
if (m_mimes.isEmpty()) {
- m_mimes << new QWindowsMimeImage << new QLastResortMimes
+ m_mimes
+#ifndef QT_NO_IMAGEFORMAT_BMP
+ << new QWindowsMimeImage
+#endif //QT_NO_IMAGEFORMAT_BMP
+ << new QLastResortMimes
<< new QWindowsMimeText << new QWindowsMimeURI
<< new QWindowsMimeHtml << new QBuiltInMimes;
m_internalMimeCount = m_mimes.size();
}
}
+QString QWindowsMimeConverter::clipboardFormatName(int cf)
+{
+ wchar_t buf[256] = {0};
+ return GetClipboardFormatName(cf, buf, 255)
+ ? QString::fromWCharArray(buf) : QString();
+}
+
QVariant QWindowsMimeConverter::convertToMime(const QStringList &mimeTypes,
IDataObject *pDataObj,
QVariant::Type preferredType,
diff --git a/src/plugins/platforms/windows/qwindowsmime.h b/src/plugins/platforms/windows/qwindowsmime.h
index 952410e14b..1ec0dccdf8 100644
--- a/src/plugins/platforms/windows/qwindowsmime.h
+++ b/src/plugins/platforms/windows/qwindowsmime.h
@@ -42,6 +42,7 @@
QT_BEGIN_NAMESPACE
+class QDebug;
class QMimeData;
class QWindowsMime
@@ -83,6 +84,8 @@ public:
void registerMime(QWindowsMime *mime);
void unregisterMime(QWindowsMime *mime) { m_mimes.removeOne(mime); }
+ static QString clipboardFormatName(int cf);
+
private:
void ensureInitialized() const;
@@ -90,6 +93,11 @@ private:
mutable int m_internalMimeCount;
};
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug, const FORMATETC &);
+QDebug operator<<(QDebug d, IDataObject *);
+#endif
+
QT_END_NAMESPACE
#endif // QWINDOWSMIME_H
diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.cpp b/src/plugins/platforms/windows/qwindowsmousehandler.cpp
index e83354157b..e26010b5c4 100644
--- a/src/plugins/platforms/windows/qwindowsmousehandler.cpp
+++ b/src/plugins/platforms/windows/qwindowsmousehandler.cpp
@@ -218,10 +218,8 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
const QPoint globalPosition = winEventPosition;
const QPoint clientPosition = QWindowsGeometryHint::mapFromGlobal(hwnd, globalPosition);
const Qt::MouseButtons buttons = QWindowsMouseHandler::queryMouseButtons();
- QWindowSystemInterface::handleFrameStrutMouseEvent(window,
- clientPosition / QWindowsScaling::factor(),
- globalPosition / QWindowsScaling::factor(),
- buttons,
+ QWindowSystemInterface::handleFrameStrutMouseEvent(window, clientPosition,
+ globalPosition, buttons,
QWindowsKeyMapper::queryKeyboardModifiers(),
source);
return false; // Allow further event processing (dragging of windows).
@@ -286,7 +284,7 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
// ChildWindowFromPointEx() may not find the Qt window (failing with ERROR_ACCESS_DENIED)
if (!currentWindowUnderMouse) {
const QRect clientRect(QPoint(0, 0), window->size());
- if (clientRect.contains(winEventPosition / QWindowsScaling::factor()))
+ if (clientRect.contains(winEventPosition))
currentWindowUnderMouse = window;
}
@@ -373,14 +371,14 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
m_windowUnderMouse = currentWindowUnderMouse;
}
- QWindowSystemInterface::handleMouseEvent(window,
- winEventPosition / QWindowsScaling::factor(),
- globalPosition / QWindowsScaling::factor(),
- buttons,
+ QWindowSystemInterface::handleMouseEvent(window, winEventPosition, globalPosition, buttons,
QWindowsKeyMapper::queryKeyboardModifiers(),
source);
m_previousCaptureWindow = hasCapture ? window : 0;
- return true;
+ // QTBUG-48117, force synchronous handling for the extra buttons so that WM_APPCOMMAND
+ // is sent for unhandled WM_XBUTTONDOWN.
+ return (msg.message != WM_XBUTTONUP && msg.message != WM_XBUTTONDOWN && msg.message != WM_XBUTTONDBLCLK)
+ || QWindowSystemInterface::flushWindowSystemEvents();
}
static bool isValidWheelReceiver(QWindow *candidate)
@@ -411,11 +409,9 @@ static void redirectWheelEvent(QWindow *window, const QPoint &globalPos, int del
}
if (handleEvent) {
- const QPoint posDip = QWindowsGeometryHint::mapFromGlobal(receiver, globalPos) / QWindowsScaling::factor();
QWindowSystemInterface::handleWheelEvent(receiver,
- posDip, globalPos / QWindowsScaling::factor(),
- delta / QWindowsScaling::factor(),
- orientation, mods);
+ QWindowsGeometryHint::mapFromGlobal(receiver, globalPos),
+ globalPos, delta, orientation, mods);
}
}
@@ -492,7 +488,12 @@ bool QWindowsMouseHandler::translateTouchEvent(QWindow *window, HWND,
return true;
}
- const QRect screenGeometry = window->screen()->geometry();
+ const QScreen *screen = window->screen();
+ if (!screen)
+ screen = QGuiApplication::primaryScreen();
+ if (!screen)
+ return true;
+ const QRect screenGeometry = screen->geometry();
const int winTouchPointCount = msg.wParam;
QScopedArrayPointer<TOUCHINPUT> winTouchInputs(new TOUCHINPUT[winTouchPointCount]);
@@ -503,7 +504,6 @@ bool QWindowsMouseHandler::translateTouchEvent(QWindow *window, HWND,
Qt::TouchPointStates allStates = 0;
QWindowsContext::user32dll.getTouchInputInfo((HANDLE) msg.lParam, msg.wParam, winTouchInputs.data(), sizeof(TOUCHINPUT));
- const qreal screenPosFactor = 0.01 / qreal(QWindowsScaling::factor());
for (int i = 0; i < winTouchPointCount; ++i) {
const TOUCHINPUT &winTouchInput = winTouchInputs[i];
int id = m_touchInputIDToTouchPointID.value(winTouchInput.dwID, -1);
@@ -517,9 +517,9 @@ bool QWindowsMouseHandler::translateTouchEvent(QWindow *window, HWND,
if (m_lastTouchPositions.contains(id))
touchPoint.normalPosition = m_lastTouchPositions.value(id);
- const QPointF screenPos = QPointF(winTouchInput.x, winTouchInput.y) * screenPosFactor;
+ const QPointF screenPos = QPointF(winTouchInput.x, winTouchInput.y) / qreal(100.);
if (winTouchInput.dwMask & TOUCHINPUTMASKF_CONTACTAREA)
- touchPoint.area.setSize(QSizeF(winTouchInput.cxContact, winTouchInput.cyContact) * screenPosFactor);
+ touchPoint.area.setSize(QSizeF(winTouchInput.cxContact, winTouchInput.cyContact) / qreal(100.));
touchPoint.area.moveCenter(screenPos);
QPointF normalPosition = QPointF(screenPos.x() / screenGeometry.width(),
screenPos.y() / screenGeometry.height());
@@ -583,7 +583,12 @@ bool QWindowsMouseHandler::translateGestureEvent(QWindow *window, HWND hwnd,
if (gi.dwID != GID_DIRECTMANIPULATION)
return true;
static QPoint lastTouchPos;
- const QRect screenGeometry = window->screen()->geometry();
+ const QScreen *screen = window->screen();
+ if (!screen)
+ screen = QGuiApplication::primaryScreen();
+ if (!screen)
+ return true;
+ const QRect screenGeometry = screen->geometry();
QWindowSystemInterface::TouchPoint touchPoint;
static QWindowSystemInterface::TouchPoint touchPoint2;
touchPoint.id = 0;//gi.dwInstanceID;
diff --git a/src/plugins/platforms/windows/qwindowsnativeimage.h b/src/plugins/platforms/windows/qwindowsnativeimage.h
index 6f9ce93ef0..80a1de1ea5 100644
--- a/src/plugins/platforms/windows/qwindowsnativeimage.h
+++ b/src/plugins/platforms/windows/qwindowsnativeimage.h
@@ -57,8 +57,6 @@ public:
HDC hdc() const { return m_hdc; }
- void setDevicePixelRatio(qreal scaleFactor) { m_image.setDevicePixelRatio(scaleFactor); }
-
static QImage::Format systemFormat();
private:
diff --git a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp
index db8b2ec094..659ef79c18 100644
--- a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp
+++ b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp
@@ -234,6 +234,8 @@ QFunctionPointer QWindowsNativeInterface::platformFunction(const QByteArray &fun
{
if (function == QWindowsWindowFunctions::setTouchWindowTouchTypeIdentifier())
return QFunctionPointer(QWindowsWindow::setTouchWindowTouchTypeStatic);
+ else if (function == QWindowsWindowFunctions::setHasBorderInFullScreenIdentifier())
+ return QFunctionPointer(QWindowsWindow::setHasBorderInFullScreenStatic);
return Q_NULLPTR;
}
diff --git a/src/plugins/platforms/windows/qwindowsole.cpp b/src/plugins/platforms/windows/qwindowsole.cpp
index 6f5a521af8..e480c1ebcf 100644
--- a/src/plugins/platforms/windows/qwindowsole.cpp
+++ b/src/plugins/platforms/windows/qwindowsole.cpp
@@ -132,12 +132,6 @@ QWindowsOleDataObject::GetData(LPFORMATETC pformatetc, LPSTGMEDIUM pmedium)
{
HRESULT hr = ResultFromScode(DATA_E_FORMATETC);
- if (QWindowsContext::verbose > 1 && lcQpaMime().isDebugEnabled()) {
- wchar_t buf[256] = {0};
- GetClipboardFormatName(pformatetc->cfFormat, buf, 255);
- qCDebug(lcQpaMime) <<__FUNCTION__ << "CF = " << pformatetc->cfFormat << QString::fromWCharArray(buf);
- }
-
if (data) {
const QWindowsMimeConverter &mc = QWindowsContext::instance()->mimeConverter();
if (QWindowsMime *converter = mc.converterFromMime(*pformatetc, data))
@@ -145,11 +139,8 @@ QWindowsOleDataObject::GetData(LPFORMATETC pformatetc, LPSTGMEDIUM pmedium)
hr = ResultFromScode(S_OK);
}
- if (QWindowsContext::verbose > 1) {
- wchar_t buf[256] = {0};
- GetClipboardFormatName(pformatetc->cfFormat, buf, 255);
- qCDebug(lcQpaMime) <<__FUNCTION__ << "CF = " << pformatetc->cfFormat << " returns 0x" << int(hr) << dec;
- }
+ if (QWindowsContext::verbose > 1 && lcQpaMime().isDebugEnabled())
+ qCDebug(lcQpaMime) <<__FUNCTION__ << *pformatetc << "returns" << hex << showbase << quint64(hr);
return hr;
}
@@ -211,7 +202,7 @@ STDMETHODIMP
QWindowsOleDataObject::EnumFormatEtc(DWORD dwDirection, LPENUMFORMATETC FAR* ppenumFormatEtc)
{
if (QWindowsContext::verbose > 1)
- qCDebug(lcQpaMime) << __FUNCTION__;
+ qCDebug(lcQpaMime) << __FUNCTION__ << "dwDirection=" << dwDirection;
if (!data)
return ResultFromScode(DATA_E_FORMATETC);
@@ -274,7 +265,7 @@ QWindowsOleEnumFmtEtc::QWindowsOleEnumFmtEtc(const QVector<FORMATETC> &fmtetcs)
m_dwRefs(1), m_nIndex(0), m_isNull(false)
{
if (QWindowsContext::verbose > 1)
- qCDebug(lcQpaMime) << __FUNCTION__;
+ qCDebug(lcQpaMime) << __FUNCTION__ << fmtetcs;
m_lpfmtetcs.reserve(fmtetcs.count());
for (int idx = 0; idx < fmtetcs.count(); ++idx) {
LPFORMATETC destetc = new FORMATETC();
diff --git a/src/plugins/platforms/windows/qwindowsopengltester.cpp b/src/plugins/platforms/windows/qwindowsopengltester.cpp
index 9ebd946ce4..fcbe488f93 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
@@ -224,7 +226,7 @@ QWindowsOpenGLTester::Renderers QWindowsOpenGLTester::detectSupportedRenderers(c
#elif defined(Q_OS_WINCE)
return QWindowsOpenGLTester::Gles;
#else
- QOpenGLConfig::Gpu qgpu = QOpenGLConfig::Gpu::fromDevice(gpu.vendorId, gpu.deviceId, gpu.driverVersion);
+ QOpenGLConfig::Gpu qgpu = QOpenGLConfig::Gpu::fromDevice(gpu.vendorId, gpu.deviceId, gpu.driverVersion, gpu.description);
SupportedRenderersCache *srCache = supportedRenderersCache();
SupportedRenderersCache::const_iterator it = srCache->find(qgpu);
if (it != srCache->cend())
@@ -250,23 +252,26 @@ QWindowsOpenGLTester::Renderers QWindowsOpenGLTester::detectSupportedRenderers(c
qCDebug(lcQpaGl) << "GPU features:" << features;
if (features.contains(QStringLiteral("disable_desktopgl"))) { // Qt-specific
- qCWarning(lcQpaGl) << "Disabling Desktop GL: " << gpu;
+ qCDebug(lcQpaGl) << "Disabling Desktop GL: " << gpu;
result &= ~QWindowsOpenGLTester::DesktopGl;
}
if (features.contains(QStringLiteral("disable_angle"))) { // Qt-specific keyword
- qCWarning(lcQpaGl) << "Disabling ANGLE: " << gpu;
+ qCDebug(lcQpaGl) << "Disabling ANGLE: " << gpu;
result &= ~QWindowsOpenGLTester::GlesMask;
} else {
if (features.contains(QStringLiteral("disable_d3d11"))) { // standard keyword
- qCWarning(lcQpaGl) << "Disabling D3D11: " << gpu;
+ qCDebug(lcQpaGl) << "Disabling D3D11: " << gpu;
result &= ~QWindowsOpenGLTester::AngleRendererD3d11;
}
if (features.contains(QStringLiteral("disable_d3d9"))) { // Qt-specific
- qCWarning(lcQpaGl) << "Disabling D3D9: " << gpu;
+ qCDebug(lcQpaGl) << "Disabling D3D9: " << gpu;
result &= ~QWindowsOpenGLTester::AngleRendererD3d9;
}
}
-
+ if (features.contains(QStringLiteral("disable_rotation"))) {
+ qCDebug(lcQpaGl) << "Disabling rotation: " << gpu;
+ result |= DisableRotationFlag;
+ }
srCache->insert(qgpu, result);
return result;
#endif // !Q_OS_WINCE && !QT_NO_OPENGL
diff --git a/src/plugins/platforms/windows/qwindowsopengltester.h b/src/plugins/platforms/windows/qwindowsopengltester.h
index 748885542d..0fad3d960e 100644
--- a/src/plugins/platforms/windows/qwindowsopengltester.h
+++ b/src/plugins/platforms/windows/qwindowsopengltester.h
@@ -36,7 +36,7 @@
#include <QtCore/QByteArray>
#include <QtCore/QFlags>
-#include <private/qversionnumber_p.h>
+#include <QtCore/qversionnumber.h>
QT_BEGIN_NAMESPACE
@@ -60,7 +60,9 @@ struct GpuDescription
QByteArray description;
};
+#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug d, const GpuDescription &gd);
+#endif
class QWindowsOpenGLTester
{
@@ -74,7 +76,9 @@ public:
AngleBackendMask = AngleRendererD3d11 | AngleRendererD3d9 | AngleRendererD3d11Warp,
Gles = 0x0010, // ANGLE/unspecified or Generic GLES for Windows CE.
GlesMask = Gles | AngleBackendMask,
- SoftwareRasterizer = 0x0020
+ SoftwareRasterizer = 0x0020,
+ RendererMask = 0x00FF,
+ DisableRotationFlag = 0x0100
};
Q_DECLARE_FLAGS(Renderers, Renderer)
diff --git a/src/plugins/platforms/windows/qwindowsscaling.cpp b/src/plugins/platforms/windows/qwindowsscaling.cpp
deleted file mode 100644
index 6ab7f254fd..0000000000
--- a/src/plugins/platforms/windows/qwindowsscaling.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-/****************************************************************************
-**
-** 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 "qwindowsscaling.h"
-#include "qwindowsscreen.h"
-
-#include <QtCore/QDebug>
-#include <QtCore/QCoreApplication>
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \class QWindowsScaling
- \brief Windows scaling utilities
-
- \internal
- \ingroup qt-lighthouse-win
-*/
-
-int QWindowsScaling::m_factor = 1;
-
-static const char devicePixelRatioEnvVar[] = "QT_DEVICE_PIXEL_RATIO";
-
-// Suggest a scale factor by checking monitor sizes.
-int QWindowsScaling::determineUiScaleFactor()
-{
- if (!qEnvironmentVariableIsSet(devicePixelRatioEnvVar))
- return 1;
- const QByteArray envDevicePixelRatioEnv = qgetenv(devicePixelRatioEnvVar);
- // Auto: Suggest a scale factor by checking monitor resolution.
- if (envDevicePixelRatioEnv == "auto") {
- const int maxResolution = QWindowsScreen::maxMonitorHorizResolution();
- return maxResolution > 180 ? maxResolution / 96 : 1;
- }
- // Get factor from environment
- bool ok = false;
- const int envFactor = envDevicePixelRatioEnv.toInt(&ok);
- return ok && envFactor > 0 ? envFactor : 1;
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsscaling.h b/src/plugins/platforms/windows/qwindowsscaling.h
deleted file mode 100644
index 39e554bbe2..0000000000
--- a/src/plugins/platforms/windows/qwindowsscaling.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/****************************************************************************
-**
-** 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 QWINDOWSSCALING_H
-#define QWINDOWSSCALING_H
-
-#include <QtGui/QRegion>
-#include <QtCore/QVector>
-#include <QtCore/QRect>
-
-QT_BEGIN_NAMESPACE
-
-enum
-#if defined(Q_COMPILER_CLASS_ENUM) || defined(Q_CC_MSVC)
- : int
-#endif
-{ QWINDOWSIZE_MAX = 16777215 };
-
-class QWindowsScaling {
-public:
- static bool isActive() { return m_factor > 1; }
- static int factor() { return m_factor; }
- static void setFactor(int factor) { m_factor = factor; }
- static int determineUiScaleFactor();
-
- // Scaling helpers for size constraints.
- static int mapToNativeConstrained(int qt)
- { return m_factor != 1 && qt > 0 && qt < QWINDOWSIZE_MAX ? qt * m_factor : qt; }
-
- static int mapFromNativeConstrained(int dp)
- { return m_factor != 1 && dp > 0 && dp < QWINDOWSIZE_MAX ? dp / m_factor : dp; }
-
- static QSize mapToNativeConstrained(const QSize &qt)
- { return QSize(mapToNativeConstrained(qt.width()), mapToNativeConstrained(qt.height())); }
-
- static QRect mapToNative(const QRect &qRect)
- {
- return QRect(qRect.x() * m_factor, qRect.y() * m_factor, qRect.width() * m_factor, qRect.height() * m_factor);
- }
-
- static QRect mapFromNative(const QRect &dp)
- {
- return isActive() ?
- QRect(dp.x() / m_factor, dp.y() / m_factor, (dp.width() + 1) / m_factor, (dp.height() + 1) / m_factor) :
- dp;
- }
-
- static QRegion mapToNative(const QRegion &regionQt)
- {
- if (!QWindowsScaling::isActive() || regionQt.isEmpty())
- return regionQt;
-
- QRegion result;
- foreach (const QRect &rectQt, regionQt.rects())
- result += QWindowsScaling::mapToNative(rectQt);
- return result;
- }
-
- static QRegion mapFromNative(const QRegion &regionDp)
- {
- if (!QWindowsScaling::isActive() || regionDp.isEmpty())
- return regionDp;
-
- QRegion result;
- foreach (const QRect &rectDp, regionDp.rects())
- result += QWindowsScaling::mapFromNative(rectDp);
- return result;
- }
-
-private:
- static int m_factor;
-};
-
-QT_END_NAMESPACE
-
-#endif // QWINDOWSSCALING_H
diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp
index 7756c77001..02696c87cd 100644
--- a/src/plugins/platforms/windows/qwindowsscreen.cpp
+++ b/src/plugins/platforms/windows/qwindowsscreen.cpp
@@ -43,6 +43,7 @@
#include <QtGui/QPixmap>
#include <QtGui/QGuiApplication>
#include <qpa/qwindowsysteminterface.h>
+#include <private/qhighdpiscaling_p.h>
#include <QtGui/QScreen>
#include <QtCore/QDebug>
@@ -171,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);
@@ -191,16 +193,7 @@ static QDebug operator<<(QDebug dbg, const QWindowsScreenData &d)
dbg << " lock screen";
return dbg;
}
-
-// Return the cursor to be shared by all screens (virtual desktop).
-static inline QSharedPointer<QPlatformCursor> sharedCursor()
-{
-#ifndef QT_NO_CURSOR
- if (const QScreen *primaryScreen = QGuiApplication::primaryScreen())
- return static_cast<const QWindowsScreen *>(primaryScreen->handle())->cursorPtr();
-#endif
- return QSharedPointer<QPlatformCursor>(new QWindowsCursor);
-}
+#endif // !QT_NO_DEBUG_STREAM
/*!
\class QWindowsScreen
@@ -213,41 +206,19 @@ static inline QSharedPointer<QPlatformCursor> sharedCursor()
QWindowsScreen::QWindowsScreen(const QWindowsScreenData &data) :
m_data(data)
#ifndef QT_NO_CURSOR
- ,m_cursor(sharedCursor())
+ , m_cursor(new QWindowsCursor(this))
#endif
{
}
-BOOL QT_WIN_CALLBACK monitorResolutionEnumCallback(HMONITOR hMonitor, HDC, LPRECT, LPARAM p)
-{
- QWindowsScreenData data;
- if (monitorData(hMonitor, &data)) {
- int *maxHorizResolution = reinterpret_cast<int *>(p);
- const int horizResolution = qRound(data.dpi.first);
- if (horizResolution > *maxHorizResolution)
- *maxHorizResolution = horizResolution;
- }
- return TRUE;
-}
-
-int QWindowsScreen::maxMonitorHorizResolution()
-{
- int result = 0;
- EnumDisplayMonitors(0, 0, monitorResolutionEnumCallback, (LPARAM)&result);
- return result;
-}
-
Q_GUI_EXPORT QPixmap qt_pixmapFromWinHBITMAP(HBITMAP bitmap, int hbitmapFormat = 0);
-QPixmap QWindowsScreen::grabWindow(WId window, int qX, int qY, int qWidth, int qHeight) const
+QPixmap QWindowsScreen::grabWindow(WId window, int x, int y, int width, int height) const
{
RECT r;
HWND hwnd = window ? (HWND)window : GetDesktopWindow();
GetClientRect(hwnd, &r);
- const int x = qX * QWindowsScaling::factor();
- const int y = qY * QWindowsScaling::factor();
- int width = qWidth * QWindowsScaling::factor();
- int height = qHeight * QWindowsScaling::factor();
+
if (width < 0) width = r.right - r.left;
if (height < 0) height = r.bottom - r.top;
@@ -271,10 +242,6 @@ QPixmap QWindowsScreen::grabWindow(WId window, int qX, int qY, int qWidth, int q
DeleteObject(bitmap);
ReleaseDC(0, display_dc);
- if (QWindowsScaling::isActive()) {
- const qreal factor = 1.0 / qreal(QWindowsScaling::factor());
- return pixmap.transformed(QTransform::fromScale(factor, factor));
- }
return pixmap;
}
@@ -285,7 +252,7 @@ QPixmap QWindowsScreen::grabWindow(WId window, int qX, int qY, int qWidth, int q
QWindow *QWindowsScreen::topLevelAt(const QPoint &point) const
{
QWindow *result = 0;
- if (QWindow *child = QWindowsScreen::windowAt(point * QWindowsScaling::factor(), CWP_SKIPINVISIBLE))
+ if (QWindow *child = QWindowsScreen::windowAt(point, CWP_SKIPINVISIBLE))
result = QWindowsWindow::topLevelOf(child);
qCDebug(lcQpaWindows) <<__FUNCTION__ << point << result;
return result;
@@ -301,16 +268,13 @@ QWindow *QWindowsScreen::windowAt(const QPoint &screenPoint, unsigned flags)
return result;
}
-QWindowsScreen *QWindowsScreen::screenOf(const QWindow *w)
+qreal QWindowsScreen::pixelDensity() const
{
- if (w)
- if (const QScreen *s = w->screen())
- if (QPlatformScreen *pscr = s->handle())
- return static_cast<QWindowsScreen *>(pscr);
- if (const QScreen *ps = QGuiApplication::primaryScreen())
- if (QPlatformScreen *ppscr = ps->handle())
- return static_cast<QWindowsScreen *>(ppscr);
- return 0;
+ // 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);
}
/*!
@@ -361,6 +325,74 @@ void QWindowsScreen::handleChanges(const QWindowsScreenData &newData)
}
}
+enum OrientationPreference // matching Win32 API ORIENTATION_PREFERENCE
+#if defined(Q_COMPILER_CLASS_ENUM) || defined(Q_CC_MSVC)
+ : DWORD
+#endif
+{
+ orientationPreferenceNone = 0,
+ orientationPreferenceLandscape = 0x1,
+ orientationPreferencePortrait = 0x2,
+ orientationPreferenceLandscapeFlipped = 0x4,
+ orientationPreferencePortraitFlipped = 0x8
+};
+
+bool QWindowsScreen::setOrientationPreference(Qt::ScreenOrientation o)
+{
+ bool result = false;
+#ifndef Q_OS_WINCE
+ if (QWindowsContext::user32dll.setDisplayAutoRotationPreferences) {
+ DWORD orientationPreference = 0;
+ switch (o) {
+ case Qt::PrimaryOrientation:
+ orientationPreference = orientationPreferenceNone;
+ break;
+ case Qt::PortraitOrientation:
+ orientationPreference = orientationPreferencePortrait;
+ break;
+ case Qt::LandscapeOrientation:
+ orientationPreference = orientationPreferenceLandscape;
+ break;
+ case Qt::InvertedPortraitOrientation:
+ orientationPreference = orientationPreferencePortraitFlipped;
+ break;
+ case Qt::InvertedLandscapeOrientation:
+ orientationPreference = orientationPreferenceLandscapeFlipped;
+ break;
+ }
+ result = QWindowsContext::user32dll.setDisplayAutoRotationPreferences(orientationPreference);
+ }
+#endif // !Q_OS_WINCE
+ return result;
+}
+
+Qt::ScreenOrientation QWindowsScreen::orientationPreference()
+{
+ Qt::ScreenOrientation result = Qt::PrimaryOrientation;
+#ifndef Q_OS_WINCE
+ if (QWindowsContext::user32dll.getDisplayAutoRotationPreferences) {
+ DWORD orientationPreference = 0;
+ if (QWindowsContext::user32dll.getDisplayAutoRotationPreferences(&orientationPreference)) {
+ switch (orientationPreference) {
+ case orientationPreferenceLandscape:
+ result = Qt::LandscapeOrientation;
+ break;
+ case orientationPreferencePortrait:
+ result = Qt::PortraitOrientation;
+ break;
+ case orientationPreferenceLandscapeFlipped:
+ result = Qt::InvertedLandscapeOrientation;
+ break;
+ case orientationPreferencePortraitFlipped:
+ result = Qt::InvertedPortraitOrientation;
+ break;
+ }
+ }
+ }
+#endif // !Q_OS_WINCE
+ return result;
+}
+
/*!
\brief Queries ClearType settings to check the pixel layout
*/
@@ -542,7 +574,7 @@ void QWindowsScreenManager::clearScreens()
const QWindowsScreen *QWindowsScreenManager::screenAtDp(const QPoint &p) const
{
foreach (QWindowsScreen *scr, m_screens) {
- if (scr->geometryDp().contains(p))
+ if (scr->geometry().contains(p))
return scr;
}
return Q_NULLPTR;
diff --git a/src/plugins/platforms/windows/qwindowsscreen.h b/src/plugins/platforms/windows/qwindowsscreen.h
index 7352c45777..b46bd88ec6 100644
--- a/src/plugins/platforms/windows/qwindowsscreen.h
+++ b/src/plugins/platforms/windows/qwindowsscreen.h
@@ -34,7 +34,6 @@
#ifndef QWINDOWSSCREEN_H
#define QWINDOWSSCREEN_H
-#include "qwindowsscaling.h"
#include "qtwindowsglobal.h"
#ifdef Q_OS_WINCE
# include "qplatformfunctions_wince.h"
@@ -43,7 +42,7 @@
#include <QtCore/QList>
#include <QtCore/QVector>
#include <QtCore/QPair>
-#include <QtCore/QSharedPointer>
+#include <QtCore/QScopedPointer>
#include <qpa/qplatformscreen.h>
QT_BEGIN_NAMESPACE
@@ -75,23 +74,19 @@ class QWindowsScreen : public QPlatformScreen
{
public:
#ifndef QT_NO_CURSOR
- typedef QSharedPointer<QPlatformCursor> CursorPtr;
+ typedef QScopedPointer<QPlatformCursor> CursorPtr;
#endif
explicit QWindowsScreen(const QWindowsScreenData &data);
- static QWindowsScreen *screenOf(const QWindow *w = 0);
-
- QRect geometryDp() const { return m_data.geometry; }
- QRect geometry() const Q_DECL_OVERRIDE { return QWindowsScaling::mapFromNative(geometryDp()); }
- QRect availableGeometryDp() const { return m_data.availableGeometry; }
- QRect availableGeometry() const Q_DECL_OVERRIDE { return QWindowsScaling::mapFromNative(availableGeometryDp()); }
+ QRect geometry() const Q_DECL_OVERRIDE { return m_data.geometry; }
+ QRect availableGeometry() const Q_DECL_OVERRIDE { return m_data.availableGeometry; }
int depth() const Q_DECL_OVERRIDE { return m_data.depth; }
QImage::Format format() const Q_DECL_OVERRIDE { return m_data.format; }
QSizeF physicalSize() const Q_DECL_OVERRIDE { return m_data.physicalSizeMM; }
- QDpi logicalDpi() const Q_DECL_OVERRIDE
- { return QDpi(m_data.dpi.first / QWindowsScaling::factor(), m_data.dpi.second / QWindowsScaling::factor()); }
- qreal devicePixelRatio() const Q_DECL_OVERRIDE { return QWindowsScaling::factor(); }
+ QDpi logicalDpi() const Q_DECL_OVERRIDE { return m_data.dpi; }
+ qreal pixelDensity() const Q_DECL_OVERRIDE;
+ qreal devicePixelRatio() const Q_DECL_OVERRIDE { return 1.0; }
qreal refreshRate() const Q_DECL_OVERRIDE { return m_data.refreshRateHz; }
QString name() const Q_DECL_OVERRIDE { return m_data.name; }
Qt::ScreenOrientation orientation() const Q_DECL_OVERRIDE { return m_data.orientation; }
@@ -102,6 +97,9 @@ public:
QPixmap grabWindow(WId window, int qX, int qY, int qWidth, int qHeight) const Q_DECL_OVERRIDE;
QPlatformScreen::SubpixelAntialiasingType subpixelAntialiasingTypeHint() const Q_DECL_OVERRIDE;
+ static Qt::ScreenOrientation orientationPreference();
+ static bool setOrientationPreference(Qt::ScreenOrientation o);
+
inline void handleChanges(const QWindowsScreenData &newData);
#ifndef QT_NO_CURSOR
@@ -112,7 +110,6 @@ public:
#endif // !QT_NO_CURSOR
const QWindowsScreenData &data() const { return m_data; }
- static int maxMonitorHorizResolution();
private:
QWindowsScreenData m_data;
diff --git a/src/plugins/platforms/windows/qwindowstabletsupport.cpp b/src/plugins/platforms/windows/qwindowstabletsupport.cpp
index 7b871be015..b27811df9e 100644
--- a/src/plugins/platforms/windows/qwindowstabletsupport.cpp
+++ b/src/plugins/platforms/windows/qwindowstabletsupport.cpp
@@ -32,7 +32,6 @@
****************************************************************************/
#include "qwindowstabletsupport.h"
-#include "qwindowsscaling.h"
#ifndef QT_NO_TABLETEVENT
@@ -55,7 +54,7 @@
#include <QtCore/private/qsystemlibrary_p.h>
// Note: The definition of the PACKET structure in pktdef.h depends on this define.
-#define PACKETDATA (PK_X | PK_Y | PK_BUTTONS | PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE | PK_ORIENTATION | PK_CURSOR | PK_Z)
+#define PACKETDATA (PK_X | PK_Y | PK_BUTTONS | PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE | PK_ORIENTATION | PK_CURSOR | PK_Z | PK_TIME)
#include <pktdef.h>
QT_BEGIN_NAMESPACE
@@ -303,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
@@ -312,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
{
@@ -343,17 +346,18 @@ QWindowsTabletDeviceData QWindowsTabletSupport::tabletInit(const quint64 uniqueI
bool QWindowsTabletSupport::translateTabletProximityEvent(WPARAM /* wParam */, LPARAM lParam)
{
+ PACKET proximityBuffer[1]; // we are only interested in the first packet in this case
+ const int totalPacks = QWindowsTabletSupport::m_winTab32DLL.wTPacketsGet(m_context, 1, proximityBuffer);
+ if (!totalPacks)
+ return false;
if (!LOWORD(lParam)) {
qCDebug(lcQpaTablet) << "leave proximity for device #" << m_currentDevice;
- QWindowSystemInterface::handleTabletLeaveProximityEvent(m_devices.at(m_currentDevice).currentDevice,
+ QWindowSystemInterface::handleTabletLeaveProximityEvent(proximityBuffer[0].pkTime,
+ m_devices.at(m_currentDevice).currentDevice,
m_devices.at(m_currentDevice).currentPointerType,
m_devices.at(m_currentDevice).uniqueId);
return true;
}
- PACKET proximityBuffer[1]; // we are only interested in the first packet in this case
- const int totalPacks = QWindowsTabletSupport::m_winTab32DLL.wTPacketsGet(m_context, 1, proximityBuffer);
- if (!totalPacks)
- return false;
const UINT currentCursor = proximityBuffer[0].pkCursor;
UINT physicalCursorId;
QWindowsTabletSupport::m_winTab32DLL.wTInfo(WTI_CURSORS + currentCursor, CSR_PHYSID, &physicalCursorId);
@@ -371,7 +375,8 @@ bool QWindowsTabletSupport::translateTabletProximityEvent(WPARAM /* wParam */, L
m_devices[m_currentDevice].currentPointerType = pointerType(currentCursor);
qCDebug(lcQpaTablet) << "enter proximity for device #"
<< m_currentDevice << m_devices.at(m_currentDevice);
- QWindowSystemInterface::handleTabletEnterProximityEvent(m_devices.at(m_currentDevice).currentDevice,
+ QWindowSystemInterface::handleTabletEnterProximityEvent(proximityBuffer[0].pkTime,
+ m_devices.at(m_currentDevice).currentDevice,
m_devices.at(m_currentDevice).currentPointerType,
m_devices.at(m_currentDevice).uniqueId);
return true;
@@ -399,8 +404,7 @@ bool QWindowsTabletSupport::translateTabletPacketEvent()
// in which case we snap the position to the mouse position.
// It seems there is no way to find out the mode programmatically, the LOGCONTEXT orgX/Y/Ext
// area is always the virtual desktop.
- const QRect virtualDesktopArea
- = QWindowsScaling::mapToNative(QGuiApplication::primaryScreen()->virtualGeometry());
+ const QRect virtualDesktopArea = QGuiApplication::primaryScreen()->virtualGeometry();
qCDebug(lcQpaTablet) << __FUNCTION__ << "processing " << packetCount
<< "target:" << QGuiApplicationPrivate::tabletPressTarget;
@@ -420,7 +424,7 @@ bool QWindowsTabletSupport::translateTabletPacketEvent()
QPoint globalPos = globalPosF.toPoint();
// Get Mouse Position and compare to tablet info
- QPoint mouseLocation = QWindowsCursor::mousePosition();
+ const QPoint mouseLocation = QWindowsCursor::mousePosition();
// Positions should be almost the same if we are in absolute
// mode. If they are not, use the mouse location.
@@ -475,9 +479,7 @@ bool QWindowsTabletSupport::translateTabletPacketEvent()
<< tiltY << "tanP:" << tangentialPressure << "rotation:" << rotation;
}
- const QPointF localPosDip = QPointF(localPos / QWindowsScaling::factor());
- const QPointF globalPosDip = globalPosF / qreal(QWindowsScaling::factor());
- QWindowSystemInterface::handleTabletEvent(target, localPosDip, globalPosDip,
+ QWindowSystemInterface::handleTabletEvent(target, packet.pkTime, QPointF(localPos), globalPosF,
currentDevice, currentPointer,
static_cast<Qt::MouseButtons>(packet.pkButtons),
pressureNew, tiltX, tiltY,
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/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp
index d3f67e9eaa..cc367ff801 100644
--- a/src/plugins/platforms/windows/qwindowstheme.cpp
+++ b/src/plugins/platforms/windows/qwindowstheme.cpp
@@ -43,7 +43,6 @@
#include "qwindowsintegration.h"
#include "qt_windows.h"
#include "qwindowsfontdatabase.h"
-#include "qwindowsscaling.h"
#ifdef Q_OS_WINCE
# include "qplatformfunctions_wince.h"
# include "winuser.h"
@@ -68,6 +67,7 @@
#include <QtGui/QPainter>
#include <QtGui/QPixmapCache>
#include <qpa/qwindowsysteminterface.h>
+#include <private/qhighdpiscaling_p.h>
#include <private/qsystemlibrary_p.h>
#include <algorithm>
@@ -131,7 +131,7 @@ static inline bool booleanSystemParametersInfo(UINT what, bool defaultValue)
return defaultValue;
}
-static inline bool dWordSystemParametersInfo(UINT what, DWORD defaultValue)
+static inline DWORD dWordSystemParametersInfo(UINT what, DWORD defaultValue)
{
DWORD result;
if (SystemParametersInfo(what, 0, &result, 0))
@@ -393,6 +393,8 @@ QVariant QWindowsTheme::themeHint(ThemeHint hint) const
return QVariant(booleanSystemParametersInfo(SPI_GETSNAPTODEFBUTTON, false));
case ContextMenuOnMouseRelease:
return QVariant(true);
+ case WheelScrollLines:
+ return QVariant(int(dWordSystemParametersInfo(SPI_GETWHEELSCROLLLINES, 3)));
default:
break;
}
@@ -495,7 +497,8 @@ static QPixmap loadIconFromShell32(int resourceId, QSizeF size)
QPixmap QWindowsTheme::standardPixmap(StandardPixmap sp, const QSizeF &size) const
{
- const int scaleFactor = QWindowsScaling::factor();
+ const QScreen *primaryScreen = QGuiApplication::primaryScreen();
+ const int scaleFactor = primaryScreen ? qRound(QHighDpiScaling::factor(primaryScreen)) : 1;
const QSizeF pixmapSize = size * scaleFactor;
int resourceId = -1;
LPCTSTR iconName = 0;
@@ -632,7 +635,7 @@ public:
static FakePointer *create(T thing)
{
- return reinterpret_cast<FakePointer *>(thing);
+ return reinterpret_cast<FakePointer *>(qintptr(thing));
}
T operator * () const
@@ -720,6 +723,7 @@ QPixmap QWindowsTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &s
iconSize|SHGFI_SYSICONINDEX;
#endif // Q_OS_WINCE
unsigned long val = 0;
+#if !defined(QT_NO_WINCE_SHELLSDK)
if (cacheableDirIcon && useDefaultFolderIcon) {
flags |= SHGFI_USEFILEATTRIBUTES;
val = SHGetFileInfo(L"dummy",
@@ -729,6 +733,7 @@ QPixmap QWindowsTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &s
val = SHGetFileInfo(reinterpret_cast<const wchar_t *>(filePath.utf16()), 0,
&info, sizeof(SHFILEINFO), flags);
}
+#endif // !QT_NO_WINCE_SHELLSDK
// Even if GetFileInfo returns a valid result, hIcon can be empty in some cases
if (val && info.hIcon) {
diff --git a/src/plugins/platforms/windows/qwindowstheme.h b/src/plugins/platforms/windows/qwindowstheme.h
index b2f8e13b64..fc004b68c8 100644
--- a/src/plugins/platforms/windows/qwindowstheme.h
+++ b/src/plugins/platforms/windows/qwindowstheme.h
@@ -51,9 +51,9 @@ public:
bool usePlatformNativeDialog(DialogType type) const Q_DECL_OVERRIDE;
QPlatformDialogHelper *createPlatformDialogHelper(DialogType type) const Q_DECL_OVERRIDE;
QVariant themeHint(ThemeHint) const Q_DECL_OVERRIDE;
- virtual const QPalette *palette(Palette type = SystemPalette) const
+ const QPalette *palette(Palette type = SystemPalette) const Q_DECL_OVERRIDE
{ return m_palettes[type]; }
- virtual const QFont *font(Font type = SystemFont) const
+ const QFont *font(Font type = SystemFont) const Q_DECL_OVERRIDE
{ return m_fonts[type]; }
QPixmap standardPixmap(StandardPixmap sp, const QSizeF &size) const Q_DECL_OVERRIDE;
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index 288f73cb8f..cac8ec5ecc 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -36,7 +36,6 @@
#include "qwindowscontext.h"
#include "qwindowsdrag.h"
#include "qwindowsscreen.h"
-#include "qwindowsscaling.h"
#include "qwindowsintegration.h"
#include "qwindowsopenglcontext.h"
#ifdef QT_NO_CURSOR
@@ -49,8 +48,9 @@
#include <QtGui/QRegion>
#include <QtGui/QOpenGLContext>
#include <private/qsystemlibrary_p.h>
-#include <private/qwindow_p.h>
+#include <private/qwindow_p.h> // QWINDOWSIZE_MAX
#include <private/qguiapplication_p.h>
+#include <private/qhighdpiscaling_p.h>
#include <qpa/qwindowsysteminterface.h>
#include <QtCore/QDebug>
@@ -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.
@@ -169,7 +185,7 @@ static QPoint windowPlacementOffset(HWND hwnd, const QPoint &point)
const QWindowsScreen *screen = screenManager.screens().size() == 1
? screenManager.screens().first() : screenManager.screenAtDp(point);
if (screen)
- return screen->availableGeometryDp().topLeft() - screen->geometryDp().topLeft();
+ return screen->availableGeometry().topLeft() - screen->geometry().topLeft();
#else
Q_UNUSED(hwnd)
Q_UNUSED(point)
@@ -608,9 +624,7 @@ QWindowsWindowData
const QString windowClassName = QWindowsContext::instance()->registerWindowClass(w);
- const QRect geometryDip = QWindowsScaling::mapFromNative(data.geometry);
- QRect fixedGeometryDip = QPlatformWindow::initialGeometry(w, geometryDip, defaultWindowWidth, defaultWindowHeight);
- const QRect rect = fixedGeometryDip != geometryDip ? QWindowsScaling::mapToNative(fixedGeometryDip) : data.geometry;
+ const QRect rect = QPlatformWindow::initialGeometry(w, data.geometry, defaultWindowWidth, defaultWindowHeight);
if (title.isEmpty() && (result.flags & Qt::WindowTitleHint))
title = topLevel ? qAppName() : w->objectName();
@@ -706,6 +720,20 @@ void WindowCreationData::initialize(const QWindow *w, HWND hwnd, bool frameChang
}
}
+
+// Scaling helpers for size constraints.
+static QSize toNativeSizeConstrained(QSize dip, const QWindow *w)
+{
+ if (QHighDpiScaling::isActive()) {
+ const qreal factor = QHighDpiScaling::factor(w);
+ if (dip.width() > 0 && dip.width() < QWINDOWSIZE_MAX)
+ dip.rwidth() *= factor;
+ if (dip.height() > 0 && dip.height() < QWINDOWSIZE_MAX)
+ dip.rheight() *= factor;
+ }
+ return dip;
+}
+
/*!
\class QWindowsGeometryHint
\brief Stores geometry constraints and provides utility functions.
@@ -718,8 +746,8 @@ void WindowCreationData::initialize(const QWindow *w, HWND hwnd, bool frameChang
*/
QWindowsGeometryHint::QWindowsGeometryHint(const QWindow *w, const QMargins &cm) :
- minimumSize(QWindowsScaling::mapToNativeConstrained(w->minimumSize())),
- maximumSize(QWindowsScaling::mapToNativeConstrained(w->maximumSize())),
+ minimumSize(toNativeSizeConstrained(w->minimumSize(), w)),
+ maximumSize(toNativeSizeConstrained(w->maximumSize(), w)),
customMargins(cm)
{
}
@@ -900,6 +928,7 @@ QWindowsWindow::QWindowsWindow(QWindow *aWindow, const QWindowsWindowData &data)
m_hdc(0),
m_windowState(Qt::WindowNoState),
m_opacity(1.0),
+ m_cursor(new CursorHandle),
m_dropTarget(0),
m_savedStyle(0),
m_format(aWindow->requestedFormat()),
@@ -953,8 +982,7 @@ void QWindowsWindow::fireExpose(const QRegion &region, bool force)
clearFlag(Exposed);
else
setFlag(Exposed);
- QWindowSystemInterface::handleExposeEvent(window(),
- QWindowsScaling::mapFromNative(region));
+ QWindowSystemInterface::handleExposeEvent(window(), region);
}
static inline QWindow *findTransientChild(const QWindow *parent)
@@ -1005,7 +1033,17 @@ void QWindowsWindow::destroyWindow()
void QWindowsWindow::updateDropSite(bool topLevel)
{
bool enabled = false;
- if (topLevel) {
+ bool parentIsEmbedded = false;
+
+ if (!topLevel) {
+ // if the parent window is a foreign window wrapped via QWindow::fromWinId, we need to enable the drop site
+ // on the first child window
+ const QWindow *parent = window()->parent();
+ if (parent && (parent->type() == Qt::ForeignWindow))
+ parentIsEmbedded = true;
+ }
+
+ if (topLevel || parentIsEmbedded) {
switch (window()->type()) {
case Qt::Window:
case Qt::Dialog:
@@ -1051,7 +1089,7 @@ QWindow *QWindowsWindow::topLevelOf(QWindow *w)
if (const QPlatformWindow *handle = w->handle()) {
const QWindowsWindow *ww = static_cast<const QWindowsWindow *>(handle);
- if (ww->isEmbedded(0)) {
+ if (ww->isEmbedded()) {
HWND parentHWND = GetAncestor(ww->handle(), GA_PARENT);
const HWND desktopHwnd = GetDesktopWindow();
const QWindowsContext *ctx = QWindowsContext::instance();
@@ -1129,12 +1167,12 @@ bool QWindowsWindow::isEmbedded(const QPlatformWindow *parentWindow) const
}
if (!m_data.embedded && parent())
- return parent()->isEmbedded(0);
+ return parent()->isEmbedded();
return m_data.embedded;
}
-QPoint QWindowsWindow::mapToGlobalDp(const QPoint &pos) const
+QPoint QWindowsWindow::mapToGlobal(const QPoint &pos) const
{
if (m_data.hwnd)
return QWindowsGeometryHint::mapToGlobal(m_data.hwnd, pos);
@@ -1142,7 +1180,7 @@ QPoint QWindowsWindow::mapToGlobalDp(const QPoint &pos) const
return pos;
}
-QPoint QWindowsWindow::mapFromGlobalDp(const QPoint &pos) const
+QPoint QWindowsWindow::mapFromGlobal(const QPoint &pos) const
{
if (m_data.hwnd)
return QWindowsGeometryHint::mapFromGlobal(m_data.hwnd, pos);
@@ -1323,22 +1361,22 @@ static QRect normalFrameGeometry(HWND hwnd)
return QRect();
}
-QRect QWindowsWindow::normalGeometryDp() const
+QRect QWindowsWindow::normalGeometry() const
{
// Check for fake 'fullscreen' mode.
const bool fakeFullScreen = m_savedFrameGeometry.isValid() && window()->windowState() == Qt::WindowFullScreen;
const QRect frame = fakeFullScreen ? m_savedFrameGeometry : normalFrameGeometry(m_data.hwnd);
- const QMargins margins = fakeFullScreen ? QWindowsGeometryHint::frame(m_savedStyle, 0) : frameMarginsDp();
+ const QMargins margins = fakeFullScreen ? QWindowsGeometryHint::frame(m_savedStyle, 0) : frameMargins();
return frame.isValid() ? frame.marginsRemoved(margins) : frame;
}
-void QWindowsWindow::setGeometryDp(const QRect &rectIn)
+void QWindowsWindow::setGeometry(const QRect &rectIn)
{
QRect rect = rectIn;
// This means it is a call from QWindow::setFramePosition() and
// the coordinates include the frame (size is still the contents rectangle).
if (QWindowsGeometryHint::positionIncludesFrame(window())) {
- const QMargins margins = frameMarginsDp();
+ const QMargins margins = frameMargins();
rect.moveTopLeft(rect.topLeft() + QPoint(margins.left(), margins.top()));
}
if (m_windowState == Qt::WindowMinimized)
@@ -1407,9 +1445,8 @@ void QWindowsWindow::handleGeometryChange()
return;
const QRect previousGeometry = m_data.geometry;
m_data.geometry = geometry_sys();
- const QRect geometryDip = QWindowsScaling::mapFromNative(m_data.geometry);
- QPlatformWindow::setGeometry(geometryDip);
- QWindowSystemInterface::handleGeometryChange(window(), geometryDip);
+ QPlatformWindow::setGeometry(m_data.geometry);
+ QWindowSystemInterface::handleGeometryChange(window(), m_data.geometry);
// QTBUG-32121: OpenGL/normal windows (with exception of ANGLE) do not receive
// expose events when shrinking, synthesize.
if (!testFlag(OpenGL_ES2) && isExposed()
@@ -1417,7 +1454,7 @@ void QWindowsWindow::handleGeometryChange()
fireExpose(QRect(QPoint(0, 0), m_data.geometry.size()), true);
}
if (previousGeometry.topLeft() != m_data.geometry.topLeft()) {
- QPlatformScreen *newScreen = screenForGeometry(geometryDip);
+ QPlatformScreen *newScreen = screenForGeometry(m_data.geometry);
if (newScreen != screen())
QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->screen());
}
@@ -1429,7 +1466,7 @@ void QWindowsWindow::handleGeometryChange()
void QWindowsWindow::setGeometry_sys(const QRect &rect) const
{
- const QMargins margins = frameMarginsDp();
+ const QMargins margins = frameMargins();
const QRect frameGeometry = rect + margins;
qCDebug(lcQpaWindows) << '>' << __FUNCTION__ << window()
@@ -1468,7 +1505,7 @@ QRect QWindowsWindow::frameGeometry_sys() const
QRect QWindowsWindow::geometry_sys() const
{
- return frameGeometry_sys().marginsRemoved(frameMarginsDp());
+ return frameGeometry_sys().marginsRemoved(frameMargins());
}
/*!
@@ -1540,7 +1577,7 @@ void QWindowsWindow::setWindowFlags(Qt::WindowFlags flags)
{
qCDebug(lcQpaWindows) << '>' << __FUNCTION__ << this << window() << "\n from: "
<< m_data.flags << "\n to: " << flags;
- const QRect oldGeometry = geometryDp();
+ const QRect oldGeometry = geometry();
if (m_data.flags != flags) {
m_data.flags = flags;
if (m_data.hwnd) {
@@ -1626,8 +1663,13 @@ void QWindowsWindow::setWindowState(Qt::WindowState state)
bool QWindowsWindow::isFullScreen_sys() const
{
- return window()->isTopLevel()
- && geometry_sys() == QWindowsScaling::mapToNative(window()->screen()->geometry());
+ const QWindow *w = window();
+ if (!w->isTopLevel())
+ return false;
+ const QScreen *screen = w->screen();
+ if (!screen)
+ screen = QGuiApplication::primaryScreen();
+ return screen && geometry_sys() == QHighDpi::toNativePixels(screen->geometry(), w);
}
/*!
@@ -1678,7 +1720,7 @@ void QWindowsWindow::setWindowState_sys(Qt::WindowState newState)
if (!m_savedStyle) {
m_savedStyle = style();
#ifndef Q_OS_WINCE
- if (oldState == Qt::WindowMinimized) {
+ if (oldState == Qt::WindowMinimized || oldState == Qt::WindowMaximized) {
const QRect nf = normalFrameGeometry(m_data.hwnd);
if (nf.isValid())
m_savedFrameGeometry = nf;
@@ -1693,19 +1735,22 @@ void QWindowsWindow::setWindowState_sys(Qt::WindowState newState)
newStyle |= WS_SYSMENU;
if (visible)
newStyle |= WS_VISIBLE;
+ if (testFlag(HasBorderInFullScreen))
+ newStyle |= WS_BORDER;
setStyle(newStyle);
// Use geometry of QWindow::screen() within creation or the virtual screen the
// window is in (QTBUG-31166, QTBUG-30724).
const QScreen *screen = window()->screen();
- const QRect rDip = screen->geometry();
- const QRect r = QWindowsScaling::mapToNative(rDip);
+ if (!screen)
+ screen = QGuiApplication::primaryScreen();
+ const QRect r = screen ? QHighDpi::toNativePixels(screen->geometry(), window()) : m_savedFrameGeometry;
const UINT swpf = SWP_FRAMECHANGED | SWP_NOACTIVATE;
const bool wasSync = testFlag(SynchronousGeometryChangeEvent);
setFlag(SynchronousGeometryChangeEvent);
SetWindowPos(m_data.hwnd, HWND_TOP, r.left(), r.top(), r.width(), r.height(), swpf);
if (!wasSync)
clearFlag(SynchronousGeometryChangeEvent);
- QWindowSystemInterface::handleGeometryChange(window(), rDip);
+ QWindowSystemInterface::handleGeometryChange(window(), r);
QWindowSystemInterface::flushWindowSystemEvents();
} else if (newState != Qt::WindowMinimized) {
// Restore saved state.
@@ -1726,7 +1771,7 @@ void QWindowsWindow::setWindowState_sys(Qt::WindowState newState)
// preserve maximized state
if (visible) {
setFlag(WithinMaximize);
- ShowWindow(m_data.hwnd, (newState == Qt::WindowMaximized) ? SW_MAXIMIZE : SW_SHOWNOACTIVATE);
+ ShowWindow(m_data.hwnd, (newState == Qt::WindowMaximized) ? SW_MAXIMIZE : SW_SHOWNA);
clearFlag(WithinMaximize);
}
m_savedStyle = 0;
@@ -1746,7 +1791,7 @@ void QWindowsWindow::setWindowState_sys(Qt::WindowState newState)
if ((oldState == Qt::WindowMinimized) != (newState == Qt::WindowMinimized)) {
if (visible)
ShowWindow(m_data.hwnd, (newState == Qt::WindowMinimized) ? SW_MINIMIZE :
- (newState == Qt::WindowMaximized) ? SW_MAXIMIZE : SW_SHOWNOACTIVATE);
+ (newState == Qt::WindowMaximized) ? SW_MAXIMIZE : SW_SHOWNORMAL);
}
qCDebug(lcQpaWindows) << '<' << __FUNCTION__ << this << window() << newState;
}
@@ -1804,7 +1849,7 @@ void QWindowsWindow::propagateSizeHints()
qCDebug(lcQpaWindows) << __FUNCTION__ << this << window();
}
-bool QWindowsWindow::handleGeometryChangingMessage(MSG *message, const QWindow *qWindow, const QMargins &marginsDp)
+bool QWindowsWindow::handleGeometryChangingMessage(MSG *message, const QWindow *qWindow, const QMargins &margins)
{
#ifndef Q_OS_WINCE
if (!qWindow->isTopLevel()) // Implement hasHeightForWidth().
@@ -1812,26 +1857,19 @@ bool QWindowsWindow::handleGeometryChangingMessage(MSG *message, const QWindow *
WINDOWPOS *windowPos = reinterpret_cast<WINDOWPOS *>(message->lParam);
if ((windowPos->flags & (SWP_NOCOPYBITS | SWP_NOSIZE)))
return false;
- const QRect suggestedFrameGeometryDp(windowPos->x, windowPos->y,
- windowPos->cx, windowPos->cy);
- const qreal factor = QWindowsScaling::factor();
- const QRect suggestedGeometryDp = suggestedFrameGeometryDp - marginsDp;
- const QRectF suggestedGeometry = QRectF(QPointF(suggestedGeometryDp.topLeft()) / factor,
- QSizeF(suggestedGeometryDp.size()) / factor);
- const QRectF correctedGeometryF =
- qt_window_private(const_cast<QWindow *>(qWindow))->closestAcceptableGeometry(suggestedGeometry);
+ const QRect suggestedFrameGeometry(windowPos->x, windowPos->y,
+ windowPos->cx, windowPos->cy);
+ const QRect suggestedGeometry = suggestedFrameGeometry - margins;
+ const QRectF correctedGeometryF = QPlatformWindow::closestAcceptableGeometry(qWindow, suggestedGeometry);
if (!correctedGeometryF.isValid())
return false;
- const QRect correctedFrameGeometryDp
- = QRectF(correctedGeometryF.topLeft() * factor,
- correctedGeometryF.size() * factor).toRect()
- + marginsDp;
- if (correctedFrameGeometryDp == suggestedFrameGeometryDp)
+ const QRect correctedFrameGeometry = correctedGeometryF.toRect() + margins;
+ if (correctedFrameGeometry == suggestedFrameGeometry)
return false;
- windowPos->x = correctedFrameGeometryDp.left();
- windowPos->y = correctedFrameGeometryDp.top();
- windowPos->cx = correctedFrameGeometryDp.width();
- windowPos->cy = correctedFrameGeometryDp.height();
+ windowPos->x = correctedFrameGeometry.left();
+ windowPos->y = correctedFrameGeometry.top();
+ windowPos->cx = correctedFrameGeometry.width();
+ windowPos->cy = correctedFrameGeometry.height();
return true;
#else // !Q_OS_WINCE
Q_UNUSED(message)
@@ -1841,11 +1879,11 @@ bool QWindowsWindow::handleGeometryChangingMessage(MSG *message, const QWindow *
bool QWindowsWindow::handleGeometryChanging(MSG *message) const
{
- const QMargins marginsDp = window()->isTopLevel() ? frameMarginsDp() : QMargins();
- return QWindowsWindow::handleGeometryChangingMessage(message, window(), marginsDp);
+ const QMargins margins = window()->isTopLevel() ? frameMargins() : QMargins();
+ return QWindowsWindow::handleGeometryChangingMessage(message, window(), margins);
}
-QMargins QWindowsWindow::frameMarginsDp() const
+QMargins QWindowsWindow::frameMargins() const
{
// Frames are invalidated by style changes (window state, flags).
// As they are also required for geometry calculations in resize
@@ -1892,17 +1930,17 @@ static inline void addRectToWinRegion(const QRect &rect, HRGN *winRegion)
}
}
-static HRGN qRegionToWinRegion(const QRegion &regionDip)
+static HRGN qRegionToWinRegion(const QRegion &region)
{
- const QVector<QRect> rects = regionDip.rects();
+ const QVector<QRect> rects = region.rects();
if (rects.isEmpty())
return NULL;
const int rectCount = rects.size();
if (rectCount == 1)
- return createRectRegion(QWindowsScaling::mapToNative(regionDip.boundingRect()));
- HRGN hRegion = createRectRegion(QWindowsScaling::mapToNative(rects.front()));
+ return createRectRegion(region.boundingRect());
+ HRGN hRegion = createRectRegion(rects.front());
for (int i = 1; i < rectCount; ++i)
- addRectToWinRegion(QWindowsScaling::mapToNative(rects.at(i)), &hRegion);
+ addRectToWinRegion(rects.at(i), &hRegion);
return hRegion;
}
@@ -1916,7 +1954,7 @@ void QWindowsWindow::setMask(const QRegion &region)
// Mask is in client area coordinates, so offset it in case we have a frame
if (window()->isTopLevel()) {
- const QMargins margins = frameMarginsDp();
+ const QMargins margins = frameMargins();
OffsetRgn(winRegion, margins.left(), margins.top());
}
@@ -2053,23 +2091,23 @@ bool QWindowsWindow::handleNonClientHitTest(const QPoint &globalPos, LRESULT *re
|| (m_data.flags & Qt::FramelessWindowHint)) {
return false;
}
- const QSize minimumSize = QWindowsScaling::mapToNativeConstrained(w->minimumSize());
+ const QSize minimumSize = w->minimumSize();
if (minimumSize.isEmpty())
return false;
- const QSize maximumSize = QWindowsScaling::mapToNativeConstrained(w->maximumSize());
+ const QSize maximumSize = w->maximumSize();
const bool fixedWidth = minimumSize.width() == maximumSize.width();
const bool fixedHeight = minimumSize.height() == maximumSize.height();
if (!fixedWidth && !fixedHeight)
return false;
- const QPoint localPos = mapFromGlobalDp(globalPos);
- const QSize size = w->size() * QWindowsScaling::factor();
+ const QPoint localPos = w->mapFromGlobal(QHighDpi::fromNativePixels(globalPos, w));
+ const QSize size = w->size();
if (fixedHeight) {
if (localPos.y() >= size.height()) {
*result = HTBORDER; // Unspecified border, no resize cursor.
return true;
}
if (localPos.y() < 0) {
- const QMargins margins = frameMarginsDp();
+ const QMargins margins = frameMargins();
const int topResizeBarPos = margins.left() - margins.top();
if (localPos.y() < topResizeBarPos) {
*result = HTCAPTION; // Extend caption over top resize bar, let's user move the window.
@@ -2088,13 +2126,13 @@ bool QWindowsWindow::handleNonClientHitTest(const QPoint &globalPos, LRESULT *re
#ifndef QT_NO_CURSOR
// Return the default cursor (Arrow) from QWindowsCursor's cache.
-static inline QWindowsWindowCursor defaultCursor(const QWindow *w)
+static inline CursorHandlePtr defaultCursor(const QWindow *w)
{
if (QScreen *screen = w->screen())
if (const QPlatformScreen *platformScreen = screen->handle())
if (QPlatformCursor *cursor = platformScreen->cursor())
return static_cast<QWindowsCursor *>(cursor)->standardWindowCursor(Qt::ArrowCursor);
- return QWindowsWindowCursor(Qt::ArrowCursor);
+ return CursorHandlePtr(new CursorHandle(QWindowsCursor::createCursorFromShape(Qt::ArrowCursor)));
}
// Check whether to apply a new cursor. Either the window in question is
@@ -2108,7 +2146,7 @@ static inline bool applyNewCursor(const QWindow *w)
for (const QWindow *p = underMouse; p ; p = p->parent()) {
if (p == w)
return true;
- if (!QWindowsWindow::baseWindowOf(p)->cursor().isNull())
+ if (!QWindowsWindow::baseWindowOf(p)->cursor()->isNull())
return false;
}
return false;
@@ -2124,25 +2162,25 @@ static inline bool applyNewCursor(const QWindow *w)
void QWindowsWindow::applyCursor()
{
#ifndef QT_NO_CURSOR
- if (m_cursor.isNull()) { // Recurse up to parent with non-null cursor. Set default for toplevel.
+ if (m_cursor->isNull()) { // Recurse up to parent with non-null cursor. Set default for toplevel.
if (const QWindow *p = window()->parent()) {
QWindowsWindow::baseWindowOf(p)->applyCursor();
} else {
- SetCursor(defaultCursor(window()).handle());
+ SetCursor(defaultCursor(window())->handle());
}
} else {
- SetCursor(m_cursor.handle());
+ SetCursor(m_cursor->handle());
}
#endif
}
-void QWindowsWindow::setCursor(const QWindowsWindowCursor &c)
+void QWindowsWindow::setCursor(const CursorHandlePtr &c)
{
#ifndef QT_NO_CURSOR
- if (c.handle() != m_cursor.handle()) {
+ if (c->handle() != m_cursor->handle()) {
const bool apply = applyNewCursor(window());
qCDebug(lcQpaWindows) << window() << __FUNCTION__
- << c.cursor().shape() << " doApply=" << apply;
+ << c->handle() << " doApply=" << apply;
m_cursor = c;
if (apply)
applyCursor();
@@ -2245,10 +2283,6 @@ void QWindowsWindow::setWindowIcon(const QIcon &icon)
The property can be set using QPlatformNativeInterface::setWindowProperty() or,
before platform window creation, by setting a dynamic property
on the QWindow (see QWindowsIntegration::createPlatformWindow()).
-
- Note: The function uses (unscaled) device pixels since the QWizard also
- uses AdjustWindowRect() and using device independent pixels would introduce
- rounding errors.
*/
void QWindowsWindow::setCustomMargins(const QMargins &newCustomMargins)
@@ -2339,4 +2373,19 @@ void QWindowsWindow::aboutToMakeCurrent()
#endif
}
+void QWindowsWindow::setHasBorderInFullScreenStatic(QWindow *window, bool border)
+{
+ if (!window->handle())
+ return;
+ static_cast<QWindowsWindow *>(window->handle())->setHasBorderInFullScreen(border);
+}
+
+void QWindowsWindow::setHasBorderInFullScreen(bool border)
+{
+ if (border)
+ setFlag(HasBorderInFullScreen);
+ else
+ clearFlag(HasBorderInFullScreen);
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h
index fff90b4b11..6fffa1e6e9 100644
--- a/src/plugins/platforms/windows/qwindowswindow.h
+++ b/src/plugins/platforms/windows/qwindowswindow.h
@@ -38,7 +38,6 @@
#ifdef Q_OS_WINCE
# include "qplatformfunctions_wince.h"
#endif
-#include "qwindowsscaling.h"
#include "qwindowscursor.h"
#include <qpa/qplatformwindow.h>
@@ -138,35 +137,28 @@ public:
WithinMaximize = 0x40000,
MaximizeToFullScreen = 0x80000,
InputMethodDisabled = 0x100000,
- Compositing = 0x200000
+ Compositing = 0x200000,
+ HasBorderInFullScreen = 0x400000
};
QWindowsWindow(QWindow *window, const QWindowsWindowData &data);
~QWindowsWindow();
+ using QPlatformWindow::screenForGeometry;
+
QSurfaceFormat format() const Q_DECL_OVERRIDE { return m_format; }
- void setGeometryDp(const QRect &rectIn);
- void setGeometry(const QRect &rect) Q_DECL_OVERRIDE
- { setGeometryDp(QWindowsScaling::mapToNative(rect)); }
- QRect geometryDp() const { return m_data.geometry; }
- QRect geometry() const Q_DECL_OVERRIDE
- { return QWindowsScaling::mapFromNative(geometryDp()); }
- QRect normalGeometryDp() const;
- QRect normalGeometry() const Q_DECL_OVERRIDE
- { return QWindowsScaling::mapFromNative(normalGeometryDp()); }
- qreal devicePixelRatio() const Q_DECL_OVERRIDE
- { return qreal(QWindowsScaling::factor()); }
+ void setGeometry(const QRect &rect) Q_DECL_OVERRIDE;
+ QRect geometry() const Q_DECL_OVERRIDE { return m_data.geometry; }
+ QRect normalGeometry() const Q_DECL_OVERRIDE;
+
void setVisible(bool visible) Q_DECL_OVERRIDE;
bool isVisible() const;
bool isExposed() const Q_DECL_OVERRIDE { return testFlag(Exposed); }
bool isActive() const Q_DECL_OVERRIDE;
- bool isEmbedded(const QPlatformWindow *parentWindow) const Q_DECL_OVERRIDE;
- QPoint mapToGlobalDp(const QPoint &pos) const;
- QPoint mapToGlobal(const QPoint &pos) const Q_DECL_OVERRIDE
- { return mapToGlobalDp(pos * QWindowsScaling::factor()) / QWindowsScaling::factor(); }
- QPoint mapFromGlobalDp(const QPoint &pos) const;
- QPoint mapFromGlobal(const QPoint &pos) const Q_DECL_OVERRIDE
- { return mapFromGlobalDp(pos * QWindowsScaling::factor()) / QWindowsScaling::factor(); }
+ bool isEmbedded(const QPlatformWindow *parentWindow = 0) const Q_DECL_OVERRIDE;
+ QPoint mapToGlobal(const QPoint &pos) const Q_DECL_OVERRIDE;
+ QPoint mapFromGlobal(const QPoint &pos) const Q_DECL_OVERRIDE;
+
void setWindowFlags(Qt::WindowFlags flags) Q_DECL_OVERRIDE;
void setWindowState(Qt::WindowState state) Q_DECL_OVERRIDE;
@@ -179,13 +171,12 @@ public:
void raise() Q_DECL_OVERRIDE;
void lower() Q_DECL_OVERRIDE;
- void windowEvent(QEvent *event);
+ void windowEvent(QEvent *event) Q_DECL_OVERRIDE;
void propagateSizeHints() Q_DECL_OVERRIDE;
static bool handleGeometryChangingMessage(MSG *message, const QWindow *qWindow, const QMargins &marginsDp);
bool handleGeometryChanging(MSG *message) const;
- QMargins frameMarginsDp() const;
- QMargins frameMargins() const Q_DECL_OVERRIDE { return frameMarginsDp() / QWindowsScaling::factor(); }
+ QMargins frameMargins() const Q_DECL_OVERRIDE;
void setOpacity(qreal level) Q_DECL_OVERRIDE;
void setMask(const QRegion &region) Q_DECL_OVERRIDE;
@@ -196,10 +187,10 @@ public:
bool setMouseGrabEnabled(bool grab) Q_DECL_OVERRIDE;
inline bool hasMouseCapture() const { return GetCapture() == m_data.hwnd; }
- bool startSystemResize(const QPoint &, Qt::Corner corner) Q_DECL_OVERRIDE;
+ bool startSystemResize(const QPoint &pos, Qt::Corner corner) Q_DECL_OVERRIDE;
- void setFrameStrutEventsEnabled(bool enabled);
- bool frameStrutEventsEnabled() const { return testFlag(FrameStrutEventsEnabled); }
+ void setFrameStrutEventsEnabled(bool enabled) Q_DECL_OVERRIDE;
+ bool frameStrutEventsEnabled() const Q_DECL_OVERRIDE { return testFlag(FrameStrutEventsEnabled); }
QMargins customMargins() const { return m_data.customMargins; }
void setCustomMargins(const QMargins &m);
@@ -235,9 +226,9 @@ public:
#endif // !Q_OS_WINCE
#ifndef QT_NO_CURSOR
- QWindowsWindowCursor cursor() const { return m_cursor; }
+ CursorHandlePtr cursor() const { return m_cursor; }
#endif
- void setCursor(const QWindowsWindowCursor &c);
+ void setCursor(const CursorHandlePtr &c);
void applyCursor();
inline bool testFlag(unsigned f) const { return (m_flags & f) != 0; }
@@ -246,22 +237,23 @@ public:
void setEnabled(bool enabled);
bool isEnabled() const;
- void setWindowIcon(const QIcon &icon);
+ void setWindowIcon(const QIcon &icon) Q_DECL_OVERRIDE;
void *surface(void *nativeConfig, int *err);
void invalidateSurface() Q_DECL_OVERRIDE;
void aboutToMakeCurrent();
#ifndef Q_OS_WINCE
- void setAlertState(bool enabled);
- bool isAlertState() const { return testFlag(AlertState); }
+ void setAlertState(bool enabled) Q_DECL_OVERRIDE;
+ bool isAlertState() const Q_DECL_OVERRIDE { return testFlag(AlertState); }
void alertWindow(int durationMs = 0);
void stopAlertWindow();
#endif
static void setTouchWindowTouchTypeStatic(QWindow *window, QWindowsWindowFunctions::TouchWindowTouchTypes touchTypes);
void registerTouchWindow(QWindowsWindowFunctions::TouchWindowTouchTypes touchTypes = QWindowsWindowFunctions::NormalTouch);
-
+ static void setHasBorderInFullScreenStatic(QWindow *window, bool border);
+ void setHasBorderInFullScreen(bool border);
private:
inline void show_sys() const;
inline void hide_sys() const;
@@ -288,7 +280,7 @@ private:
Qt::WindowState m_windowState;
qreal m_opacity;
#ifndef QT_NO_CURSOR
- QWindowsWindowCursor m_cursor;
+ CursorHandlePtr m_cursor;
#endif
QWindowsOleDropTarget *m_dropTarget;
unsigned m_savedStyle;
@@ -302,12 +294,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/windows/windows.pri b/src/plugins/platforms/windows/windows.pri
index de901aaeb1..67af5c03ef 100644
--- a/src/plugins/platforms/windows/windows.pri
+++ b/src/plugins/platforms/windows/windows.pri
@@ -13,7 +13,6 @@ wince: DEFINES *= QT_LIBINFIX=L"\"\\\"$${QT_LIBINFIX}\\\"\""
DEFINES *= QT_NO_CAST_FROM_ASCII
contains(QT_CONFIG, directwrite) {
- LIBS *= -ldwrite
SOURCES += $$PWD/qwindowsfontenginedirectwrite.cpp
HEADERS += $$PWD/qwindowsfontenginedirectwrite.h
} else {
@@ -29,7 +28,6 @@ SOURCES += \
$$PWD/qwindowsfontengine.cpp \
$$PWD/qwindowsfontdatabase.cpp \
$$PWD/qwindowsmousehandler.cpp \
- $$PWD/qwindowsguieventdispatcher.cpp \
$$PWD/qwindowsole.cpp \
$$PWD/qwindowsmime.cpp \
$$PWD/qwindowsinternalmimedata.cpp \
@@ -40,7 +38,6 @@ SOURCES += \
$$PWD/qwindowsservices.cpp \
$$PWD/qwindowsnativeimage.cpp \
$$PWD/qwindowsnativeinterface.cpp \
- $$PWD/qwindowsscaling.cpp \
$$PWD/qwindowsopengltester.cpp
HEADERS += \
@@ -52,7 +49,6 @@ HEADERS += \
$$PWD/qwindowsfontengine.h \
$$PWD/qwindowsfontdatabase.h \
$$PWD/qwindowsmousehandler.h \
- $$PWD/qwindowsguieventdispatcher.h \
$$PWD/qtwindowsglobal.h \
$$PWD/qtwindows_additional.h \
$$PWD/qwindowsole.h \
@@ -67,7 +63,6 @@ HEADERS += \
$$PWD/qplatformfunctions_wince.h \
$$PWD/qwindowsnativeimage.h \
$$PWD/qwindowsnativeinterface.h \
- $$PWD/qwindowsscaling.h \
$$PWD/qwindowsopengltester.h
INCLUDEPATH += $$PWD
@@ -136,3 +131,6 @@ contains(QT_CONFIG, freetype) {
}
contains(QT_CONFIG, accessibility):include($$PWD/accessible/accessible.pri)
+
+DEFINES *= LIBEGL_NAME=$${LIBEGL_NAME}
+DEFINES *= LIBGLESV2_NAME=$${LIBGLESV2_NAME}