summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--INSTALL1
-rw-r--r--mkspecs/common/mac.conf2
-rw-r--r--mkspecs/common/msvc-version.conf5
-rw-r--r--mkspecs/devices/linux-rasp-pi-g++/qmake.conf4
-rw-r--r--mkspecs/devices/linux-rasp-pi2-g++/qmake.conf5
-rw-r--r--mkspecs/devices/linux-rasp-pi3-g++/qmake.conf4
-rw-r--r--mkspecs/features/mac/sdk.prf4
-rw-r--r--mkspecs/hurd-g++/qplatformdefs.h1
-rw-r--r--qmake/generators/win32/msvc_objectmodel.cpp3
-rw-r--r--qmake/generators/win32/msvc_objectmodel.h3
-rw-r--r--qmake/generators/win32/msvc_vcproj.cpp24
-rw-r--r--qmake/library/ioutils.cpp7
-rw-r--r--src/corelib/kernel/qcore_mac_objc.mm49
-rw-r--r--src/gui/configure.json3
-rw-r--r--src/gui/painting/qbackingstore.cpp41
-rw-r--r--src/gui/text/qtextdocumentfragment.cpp3
-rw-r--r--src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp4
-rw-r--r--src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_ft.cpp45
-rw-r--r--src/plugins/platforms/cocoa/qcocoascreen.mm5
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm6
-rw-r--r--src/plugins/platforms/cocoa/qnswindowdelegate.mm34
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp1
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmwindow.cpp4
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp20
-rw-r--r--src/plugins/platforms/windows/qwindowspointerhandler.cpp483
-rw-r--r--src/plugins/platforms/windows/qwindowspointerhandler.h6
-rw-r--r--src/plugins/platforms/winrt/qwinrtscreen.cpp18
-rw-r--r--src/plugins/platforms/winrt/qwinrtscreen.h3
-rw-r--r--src/plugins/platforms/winrt/qwinrtwindow.cpp5
-rw-r--r--src/widgets/kernel/qwidget.cpp109
-rw-r--r--src/widgets/kernel/qwidget_p.h1
-rw-r--r--src/widgets/kernel/qwidgetwindow.cpp2
-rw-r--r--src/widgets/widgets/qcalendarwidget.cpp27
-rw-r--r--tests/auto/gui/qopengl/tst_qopengl.cpp2
-rw-r--r--tests/auto/gui/text/qtextdocumentfragment/tst_qtextdocumentfragment.cpp22
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsitem/BLACKLIST3
-rw-r--r--tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp10
37 files changed, 461 insertions, 508 deletions
diff --git a/INSTALL b/INSTALL
index 7c14b301f8..d0976a92ae 100644
--- a/INSTALL
+++ b/INSTALL
@@ -7,4 +7,3 @@ or follow one of these links:
Mac OS X: http://doc.qt.io/qt-%SHORTVERSION%/osx-building.html
Windows: http://doc.qt.io/qt-%SHORTVERSION%/windows-building.html
X11 Platforms: http://doc.qt.io/qt-%SHORTVERSION%/linux-building.html
-Windows CE: http://doc.qt.io/qt-%SHORTVERSION%/install-wince.html
diff --git a/mkspecs/common/mac.conf b/mkspecs/common/mac.conf
index b77494ec9b..e000d1026b 100644
--- a/mkspecs/common/mac.conf
+++ b/mkspecs/common/mac.conf
@@ -17,7 +17,7 @@ QMAKE_EXTENSION_SHLIB = dylib
QMAKE_EXTENSIONS_AUX_SHLIB = tbd
QMAKE_LIBDIR =
-# sdk.prf will prefix the proper SDK sysroot
+# The proper SDK sysroot will be automatically prepended
QMAKE_INCDIR_OPENGL = \
/System/Library/Frameworks/OpenGL.framework/Headers \
/System/Library/Frameworks/AGL.framework/Headers/
diff --git a/mkspecs/common/msvc-version.conf b/mkspecs/common/msvc-version.conf
index de8ba56b7b..06af6abf13 100644
--- a/mkspecs/common/msvc-version.conf
+++ b/mkspecs/common/msvc-version.conf
@@ -113,4 +113,9 @@ greaterThan(QMAKE_MSC_VER, 1910) {
COMPAT_MKSPEC =
}
+greaterThan(QMAKE_MSC_VER, 1919) {
+ # Visual Studio 2019 (16.0) / Visual C++ 19.20 and up
+ MSVC_VER = 16.0
+}
+
!isEmpty(COMPAT_MKSPEC):!$$COMPAT_MKSPEC: CONFIG += $$COMPAT_MKSPEC
diff --git a/mkspecs/devices/linux-rasp-pi-g++/qmake.conf b/mkspecs/devices/linux-rasp-pi-g++/qmake.conf
index b72091373d..6ec7817efb 100644
--- a/mkspecs/devices/linux-rasp-pi-g++/qmake.conf
+++ b/mkspecs/devices/linux-rasp-pi-g++/qmake.conf
@@ -20,6 +20,10 @@ QMAKE_INCDIR_OPENVG = $${QMAKE_INCDIR_EGL}
QMAKE_LIBS_EGL = -lEGL -lGLESv2
QMAKE_LIBS_OPENVG = -lEGL -lOpenVG -lGLESv2
+QMAKE_INCDIR_BCM_HOST = $$[QT_SYSROOT]/opt/vc/include
+QMAKE_LIBDIR_BCM_HOST = $$[QT_SYSROOT]/opt/vc/lib
+QMAKE_LIBS_BCM_HOST = -lbcm_host
+
contains(DISTRO, squeeze) {
#Debian Squeeze: Legacy everything
QMAKE_LIBS_OPENGL_ES2 = -lGLESv2 -lEGL
diff --git a/mkspecs/devices/linux-rasp-pi2-g++/qmake.conf b/mkspecs/devices/linux-rasp-pi2-g++/qmake.conf
index ffe8f5739a..3b49f19a5b 100644
--- a/mkspecs/devices/linux-rasp-pi2-g++/qmake.conf
+++ b/mkspecs/devices/linux-rasp-pi2-g++/qmake.conf
@@ -16,6 +16,11 @@ QMAKE_INCDIR_OPENVG = $${QMAKE_INCDIR_EGL}
QMAKE_LIBS_EGL = -lEGL -lGLESv2
QMAKE_LIBS_OPENVG = -lEGL -lOpenVG -lGLESv2
+
+QMAKE_INCDIR_BCM_HOST = $$[QT_SYSROOT]/opt/vc/include
+QMAKE_LIBDIR_BCM_HOST = $$[QT_SYSROOT]/opt/vc/lib
+QMAKE_LIBS_BCM_HOST = -lbcm_host
+
QMAKE_CFLAGS += -march=armv7-a -marm -mthumb-interwork -mfpu=neon-vfpv4 -mtune=cortex-a7 -mabi=aapcs-linux
QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
diff --git a/mkspecs/devices/linux-rasp-pi3-g++/qmake.conf b/mkspecs/devices/linux-rasp-pi3-g++/qmake.conf
index 2bb70ffb5a..b215833486 100644
--- a/mkspecs/devices/linux-rasp-pi3-g++/qmake.conf
+++ b/mkspecs/devices/linux-rasp-pi3-g++/qmake.conf
@@ -31,6 +31,10 @@ QMAKE_LIBS_OPENGL_ES2 = $${VC_LINK_LINE} -lGLESv2
# The official opt vc EGL references GLESv2 symbols: need to link it
QMAKE_LIBS_EGL = $${VC_LINK_LINE} -lEGL -lGLESv2
+QMAKE_LIBDIR_BCM_HOST = $$VC_LIBRARY_PATH
+QMAKE_INCDIR_BCM_HOST = $$VC_INCLUDE_PATH
+QMAKE_LIBS_BCM_HOST = -lbcm_host
+
QMAKE_CFLAGS = -march=armv8-a -mtune=cortex-a53 -mfpu=crypto-neon-fp-armv8
QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
diff --git a/mkspecs/features/mac/sdk.prf b/mkspecs/features/mac/sdk.prf
index 8360dd8b38..50a41657d8 100644
--- a/mkspecs/features/mac/sdk.prf
+++ b/mkspecs/features/mac/sdk.prf
@@ -33,10 +33,6 @@ QMAKE_MAC_SDK_PATH = $$xcodeSDKInfo(Path)
QMAKE_MAC_SDK_PLATFORM_PATH = $$xcodeSDKInfo(PlatformPath)
QMAKE_MAC_SDK_VERSION = $$xcodeSDKInfo(SDKVersion)
-sysrootified =
-for(val, QMAKE_INCDIR_OPENGL): sysrootified += $${QMAKE_MAC_SDK_PATH}$$val
-QMAKE_INCDIR_OPENGL = $$sysrootified
-
QMAKESPEC_NAME = $$basename(QMAKESPEC)
# Resolve SDK version of various tools
diff --git a/mkspecs/hurd-g++/qplatformdefs.h b/mkspecs/hurd-g++/qplatformdefs.h
index 3c80cbdfad..b1887aae7f 100644
--- a/mkspecs/hurd-g++/qplatformdefs.h
+++ b/mkspecs/hurd-g++/qplatformdefs.h
@@ -59,6 +59,7 @@
// We are hot - unistd.h should have turned on the specific APIs we requested
+#include <features.h>
#include <pthread.h>
#include <dirent.h>
#include <fcntl.h>
diff --git a/qmake/generators/win32/msvc_objectmodel.cpp b/qmake/generators/win32/msvc_objectmodel.cpp
index 7caa94c512..cf0b96ec9f 100644
--- a/qmake/generators/win32/msvc_objectmodel.cpp
+++ b/qmake/generators/win32/msvc_objectmodel.cpp
@@ -55,7 +55,8 @@ static DotNET vsVersionFromString(const char *versionString)
{ "11.0", NET2012 },
{ "12.0", NET2013 },
{ "14.0", NET2015 },
- { "15.0", NET2017 }
+ { "15.0", NET2017 },
+ { "16.0", NET2019 }
};
DotNET result = NETUnknown;
for (const auto entry : mapping) {
diff --git a/qmake/generators/win32/msvc_objectmodel.h b/qmake/generators/win32/msvc_objectmodel.h
index f8f9804c27..33a96bf85e 100644
--- a/qmake/generators/win32/msvc_objectmodel.h
+++ b/qmake/generators/win32/msvc_objectmodel.h
@@ -52,7 +52,8 @@ enum DotNET {
NET2012 = 0xb0,
NET2013 = 0xc0,
NET2015 = 0xd0,
- NET2017 = 0xe0
+ NET2017 = 0xe0,
+ NET2019
};
DotNET vsVersionFromString(const ProString &versionString);
diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp
index d231260886..0874a6d273 100644
--- a/qmake/generators/win32/msvc_vcproj.cpp
+++ b/qmake/generators/win32/msvc_vcproj.cpp
@@ -73,7 +73,9 @@ const char _slnHeader120[] = "Microsoft Visual Studio Solution File, Format
const char _slnHeader140[] = "Microsoft Visual Studio Solution File, Format Version 12.00"
"\n# Visual Studio 2015";
const char _slnHeader141[] = "Microsoft Visual Studio Solution File, Format Version 12.00"
- "\n# Visual Studio 2017";
+ "\n# Visual Studio 15";
+const char _slnHeader142[] = "Microsoft Visual Studio Solution File, Format Version 12.00"
+ "\n# Visual Studio Version 16";
// The following UUID _may_ change for later servicepacks...
// If so we need to search through the registry at
// HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\7.0\Projects
@@ -305,6 +307,8 @@ QString VcprojGenerator::retrievePlatformToolSet() const
return QStringLiteral("v140");
case NET2017:
return QStringLiteral("v141");
+ case NET2019:
+ return QStringLiteral("v142");
default:
return QString();
}
@@ -531,6 +535,9 @@ void VcprojGenerator::writeSubDirs(QTextStream &t)
}
switch (vcProject.Configuration.CompilerVersion) {
+ case NET2019:
+ t << _slnHeader142;
+ break;
case NET2017:
t << _slnHeader141;
break;
@@ -881,6 +888,9 @@ void VcprojGenerator::initProject()
// Own elements -----------------------------
vcProject.Name = project->first("QMAKE_ORIG_TARGET").toQString();
switch (vcProject.Configuration.CompilerVersion) {
+ case NET2019:
+ vcProject.Version = "16.00";
+ break;
case NET2017:
vcProject.Version = "15.00";
break;
@@ -1548,14 +1558,14 @@ void VcprojGenerator::initExtraCompilerOutputs()
extraCompile.Filter = "";
extraCompile.Guid = QString(_GUIDExtraCompilerFiles) + "-" + (*it);
- // If the extra compiler has a variable_out set the output file
- // is added to an other file list, and does not need its own..
bool addOnInput = hasBuiltinCompiler(firstExpandedOutputFileName(*it));
- const ProString &tmp_other_out = project->first(ProKey(*it + ".variable_out"));
- if (!tmp_other_out.isEmpty() && !addOnInput)
- continue;
-
if (!addOnInput) {
+ // If the extra compiler has a variable_out set that is already handled
+ // some other place, ignore it.
+ const ProString &outputVar = project->first(ProKey(*it + ".variable_out"));
+ if (!outputVar.isEmpty() && otherFilters.contains(outputVar))
+ continue;
+
QString tmp_out = project->first(ProKey(*it + ".output")).toQString();
if (project->values(ProKey(*it + ".CONFIG")).indexOf("combine") != -1) {
// Combined output, only one file result
diff --git a/qmake/library/ioutils.cpp b/qmake/library/ioutils.cpp
index 2b2c6d0078..3e49a99cd5 100644
--- a/qmake/library/ioutils.cpp
+++ b/qmake/library/ioutils.cpp
@@ -77,7 +77,12 @@ bool IoUtils::isRelativePath(const QString &path)
&& (path.at(2) == QLatin1Char('/') || path.at(2) == QLatin1Char('\\'))) {
return false;
}
- // (... unless, of course, they're UNC, which qmake fails on anyway)
+ // ... unless, of course, they're UNC:
+ if (path.length() >= 2
+ && (path.at(0).unicode() == '\\' || path.at(0).unicode() == '/')
+ && path.at(1) == path.at(0)) {
+ return false;
+ }
#else
if (path.startsWith(QLatin1Char('/')))
return false;
diff --git a/src/corelib/kernel/qcore_mac_objc.mm b/src/corelib/kernel/qcore_mac_objc.mm
index bc23e821fd..4550891e2a 100644
--- a/src/corelib/kernel/qcore_mac_objc.mm
+++ b/src/corelib/kernel/qcore_mac_objc.mm
@@ -48,6 +48,11 @@
#include <UIKit/UIKit.h>
#endif
+#include <execinfo.h>
+#include <dlfcn.h>
+#include <cxxabi.h>
+#include <objc/runtime.h>
+
#include <qdebug.h>
QT_BEGIN_NAMESPACE
@@ -127,12 +132,54 @@ QT_USE_NAMESPACE
}
@end
QT_NAMESPACE_ALIAS_OBJC_CLASS(QMacAutoReleasePoolTracker);
+
QT_BEGIN_NAMESPACE
QMacAutoReleasePool::QMacAutoReleasePool()
: pool([[NSAutoreleasePool alloc] init])
{
- [[[QMacAutoReleasePoolTracker alloc] initWithPool:
+ Class trackerClass = [QMacAutoReleasePoolTracker class];
+
+#ifdef QT_DEBUG
+ void *poolFrame = nullptr;
+ if (__builtin_available(macOS 10.14, iOS 12.0, tvOS 12.0, watchOS 5.0, *)) {
+ void *frame;
+ if (backtrace_from_fp(__builtin_frame_address(0), &frame, 1))
+ poolFrame = frame;
+ } else {
+ static const int maxFrames = 3;
+ void *callstack[maxFrames];
+ if (backtrace(callstack, maxFrames) == maxFrames)
+ poolFrame = callstack[maxFrames - 1];
+ }
+
+ if (poolFrame) {
+ Dl_info info;
+ if (dladdr(poolFrame, &info) && info.dli_sname) {
+ const char *symbolName = info.dli_sname;
+ if (symbolName[0] == '_') {
+ int status;
+ if (char *demangled = abi::__cxa_demangle(info.dli_sname, nullptr, 0, &status))
+ symbolName = demangled;
+ }
+
+ char *className = nullptr;
+ asprintf(&className, " ^-- allocated in function: %s", symbolName);
+
+ if (Class existingClass = objc_getClass(className))
+ trackerClass = existingClass;
+ else
+ trackerClass = objc_duplicateClass(trackerClass, className, 0);
+
+ free(className);
+
+ if (symbolName != info.dli_sname)
+ free((char*)symbolName);
+ }
+ }
+#endif
+
+ [[[trackerClass alloc] initWithPool:
reinterpret_cast<NSAutoreleasePool **>(&pool)] autorelease];
}
diff --git a/src/gui/configure.json b/src/gui/configure.json
index 4420b81409..b5bfdc4a33 100644
--- a/src/gui/configure.json
+++ b/src/gui/configure.json
@@ -59,8 +59,9 @@
},
"bcm_host": {
"export": "",
+ "headers": ["bcm_host.h"],
"sources": [
- "-lbcm_host"
+ { "type": "makeSpec", "spec": "BCM_HOST" }
]
},
"dxguid": {
diff --git a/src/gui/painting/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp
index 8d71d1c3a9..d935deb4d6 100644
--- a/src/gui/painting/qbackingstore.cpp
+++ b/src/gui/painting/qbackingstore.cpp
@@ -62,7 +62,7 @@ public:
}
QWindow *window;
- QPlatformBackingStore *platformBackingStore;
+ QPlatformBackingStore *platformBackingStore = nullptr;
QScopedPointer<QImage> highDpiBackingstore;
QRegion staticContents;
QSize size;
@@ -95,8 +95,6 @@ public:
QBackingStore::QBackingStore(QWindow *window)
: d_ptr(new QBackingStorePrivate(window))
{
- d_ptr->platformBackingStore = QGuiApplicationPrivate::platformIntegration()->createPlatformBackingStore(window);
- d_ptr->platformBackingStore->setBackingStore(this);
}
/*!
@@ -131,7 +129,8 @@ void QBackingStore::beginPaint(const QRegion &region)
d_ptr->highDpiBackingstore->devicePixelRatio() != d_ptr->window->devicePixelRatio())
resize(size());
- d_ptr->platformBackingStore->beginPaint(QHighDpi::toNativeLocalRegion(region, d_ptr->window));
+ QPlatformBackingStore *platformBackingStore = handle();
+ platformBackingStore->beginPaint(QHighDpi::toNativeLocalRegion(region, d_ptr->window));
// When QtGui is applying a high-dpi scale factor the backing store
// creates a "large" backing store image. This image needs to be
@@ -139,7 +138,7 @@ void QBackingStore::beginPaint(const QRegion &region)
// devicePixelRatio. Do this on a separate image instance that shares
// the image data to avoid having the new devicePixelRatio be propagated
// back to the platform plugin.
- QPaintDevice *device = d_ptr->platformBackingStore->paintDevice();
+ QPaintDevice *device = platformBackingStore->paintDevice();
if (QHighDpiScaling::isActive() && device->devType() == QInternal::Image) {
QImage *source = static_cast<QImage *>(device);
const bool needsNewImage = d_ptr->highDpiBackingstore.isNull()
@@ -168,7 +167,7 @@ void QBackingStore::beginPaint(const QRegion &region)
*/
QPaintDevice *QBackingStore::paintDevice()
{
- QPaintDevice *device = d_ptr->platformBackingStore->paintDevice();
+ QPaintDevice *device = handle()->paintDevice();
if (QHighDpiScaling::isActive() && device->devType() == QInternal::Image)
return d_ptr->highDpiBackingstore.data();
@@ -189,7 +188,18 @@ void QBackingStore::endPaint()
if (paintDevice()->paintingActive())
qWarning() << "QBackingStore::endPaint() called with active painter on backingstore paint device";
- d_ptr->platformBackingStore->endPaint();
+ handle()->endPaint();
+}
+
+static bool isRasterSurface(QWindow *window)
+{
+ switch (window->surfaceType()) {
+ case QSurface::RasterSurface:
+ case QSurface::RasterGLSurface:
+ return true;
+ default:
+ return false;
+ };
}
/*!
@@ -220,6 +230,13 @@ void QBackingStore::flush(const QRegion &region, QWindow *window, const QPoint &
return;
}
+ if (!isRasterSurface(window)) {
+ qWarning() << "Attempted flush to non-raster surface" << window << "of type" << window->surfaceType()
+ << (window->inherits("QWidgetWindow") ? "(consider using Qt::WA_PaintOnScreen to exclude "
+ "from backingstore sync)" : "");
+ return;
+ }
+
#ifdef QBACKINGSTORE_DEBUG
if (window && window->isTopLevel() && !qt_window_private(window)->receivedExpose) {
qWarning().nospace() << "QBackingStore::flush() called with non-exposed window "
@@ -229,7 +246,7 @@ void QBackingStore::flush(const QRegion &region, QWindow *window, const QPoint &
Q_ASSERT(window == topLevelWindow || topLevelWindow->isAncestorOf(window, QWindow::ExcludeTransients));
- d_ptr->platformBackingStore->flush(window, QHighDpi::toNativeLocalRegion(region, window),
+ handle()->flush(window, QHighDpi::toNativeLocalRegion(region, window),
QHighDpi::toNativeLocalPosition(offset, window));
}
@@ -241,7 +258,7 @@ void QBackingStore::flush(const QRegion &region, QWindow *window, const QPoint &
void QBackingStore::resize(const QSize &size)
{
d_ptr->size = size;
- d_ptr->platformBackingStore->resize(QHighDpi::toNativePixels(size, d_ptr->window), d_ptr->staticContents);
+ handle()->resize(QHighDpi::toNativePixels(size, d_ptr->window), d_ptr->staticContents);
}
/*!
@@ -268,7 +285,7 @@ bool QBackingStore::scroll(const QRegion &area, int dx, int dy)
if (qFloor(nativeDx) != nativeDx || qFloor(nativeDy) != nativeDy)
return false;
- return d_ptr->platformBackingStore->scroll(QHighDpi::toNativeLocalRegion(area, d_ptr->window),
+ return handle()->scroll(QHighDpi::toNativeLocalRegion(area, d_ptr->window),
nativeDx, nativeDy);
}
@@ -349,6 +366,10 @@ void Q_GUI_EXPORT qt_scrollRectInImage(QImage &img, const QRect &rect, const QPo
*/
QPlatformBackingStore *QBackingStore::handle() const
{
+ if (!d_ptr->platformBackingStore) {
+ d_ptr->platformBackingStore = QGuiApplicationPrivate::platformIntegration()->createPlatformBackingStore(d_ptr->window);
+ d_ptr->platformBackingStore->setBackingStore(const_cast<QBackingStore*>(this));
+ }
return d_ptr->platformBackingStore;
}
diff --git a/src/gui/text/qtextdocumentfragment.cpp b/src/gui/text/qtextdocumentfragment.cpp
index d2fe87d560..aef4ea1522 100644
--- a/src/gui/text/qtextdocumentfragment.cpp
+++ b/src/gui/text/qtextdocumentfragment.cpp
@@ -1141,7 +1141,8 @@ QTextHtmlImporter::ProcessNodeResult QTextHtmlImporter::processBlockNode()
// ####################
// block.setFloatPosition(node->cssFloat);
- if (wsm == QTextHtmlParserNode::WhiteSpacePre) {
+ if (wsm == QTextHtmlParserNode::WhiteSpacePre
+ || wsm == QTextHtmlParserNode::WhiteSpaceNoWrap) {
block.setNonBreakableLines(true);
modifiedBlockFormat = true;
}
diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp
index aa2d36423d..10df85f68e 100644
--- a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp
+++ b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp
@@ -1429,8 +1429,8 @@ QT_WARNING_POP
reinterpret_cast<const OS2Table *>(fontData.constData()
+ qFromBigEndian<quint32>(os2TableEntry->offset));
- bool italic = qFromBigEndian<quint16>(os2Table->selection) & 1;
- bool oblique = qFromBigEndian<quint16>(os2Table->selection) & 128;
+ bool italic = qFromBigEndian<quint16>(os2Table->selection) & (1 << 0);
+ bool oblique = qFromBigEndian<quint16>(os2Table->selection) & (1 << 9);
if (italic)
fontEngine->fontDef.style = QFont::StyleItalic;
diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_ft.cpp b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_ft.cpp
index f68ea54dcf..db2186644b 100644
--- a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_ft.cpp
+++ b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_ft.cpp
@@ -115,30 +115,33 @@ static FontKeys &fontKeys()
{
static FontKeys result;
if (result.isEmpty()) {
- const QSettings fontRegistry(QStringLiteral("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts"),
- QSettings::NativeFormat);
- const QStringList allKeys = fontRegistry.allKeys();
- const QString trueType = QStringLiteral("(TrueType)");
+ const QStringList keys = { QStringLiteral("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts"),
+ QStringLiteral("HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts") };
+ for (const auto key : keys) {
+ const QSettings fontRegistry(key, QSettings::NativeFormat);
+ const QStringList allKeys = fontRegistry.allKeys();
+ const QString trueType = QStringLiteral("(TrueType)");
#if QT_CONFIG(regularexpression)
- const QRegularExpression sizeListMatch(QStringLiteral("\\s(\\d+,)+\\d+"));
+ const QRegularExpression sizeListMatch(QStringLiteral("\\s(\\d+,)+\\d+"));
#else
- const QRegExp sizeListMatch(QLatin1String("\\s(\\d+,)+\\d+"));
+ const QRegExp sizeListMatch(QLatin1String("\\s(\\d+,)+\\d+"));
#endif
- Q_ASSERT(sizeListMatch.isValid());
- const int size = allKeys.size();
- result.reserve(size);
- for (int i = 0; i < size; ++i) {
- FontKey fontKey;
- const QString &registryFontKey = allKeys.at(i);
- fontKey.fileName = fontRegistry.value(registryFontKey).toString();
- QString realKey = registryFontKey;
- realKey.remove(trueType);
- realKey.remove(sizeListMatch);
- const auto fontNames = QStringRef(&realKey).trimmed().split(QLatin1Char('&'));
- fontKey.fontNames.reserve(fontNames.size());
- for (const QStringRef &fontName : fontNames)
- fontKey.fontNames.append(fontName.trimmed().toString());
- result.append(fontKey);
+ Q_ASSERT(sizeListMatch.isValid());
+ const int size = allKeys.size();
+ result.reserve(result.size() + size);
+ for (int i = 0; i < size; ++i) {
+ FontKey fontKey;
+ const QString &registryFontKey = allKeys.at(i);
+ fontKey.fileName = fontRegistry.value(registryFontKey).toString();
+ QString realKey = registryFontKey;
+ realKey.remove(trueType);
+ realKey.remove(sizeListMatch);
+ const auto fontNames = QStringRef(&realKey).trimmed().split(QLatin1Char('&'));
+ fontKey.fontNames.reserve(fontNames.size());
+ for (const QStringRef &fontName : fontNames)
+ fontKey.fontNames.append(fontName.trimmed().toString());
+ result.append(fontKey);
+ }
}
}
return result;
diff --git a/src/plugins/platforms/cocoa/qcocoascreen.mm b/src/plugins/platforms/cocoa/qcocoascreen.mm
index 36c11ba8af..830a387fd1 100644
--- a/src/plugins/platforms/cocoa/qcocoascreen.mm
+++ b/src/plugins/platforms/cocoa/qcocoascreen.mm
@@ -269,15 +269,14 @@ struct DeferredDebugHelper
void QCocoaScreen::deliverUpdateRequests()
{
- if (!QGuiApplication::instance())
- return;
+ QMacAutoReleasePool pool;
// The CVDisplayLink callback is a notification that it's a good time to produce a new frame.
// Since the callback is delivered on a separate thread we have to marshal it over to the
// main thread, as Qt requires update requests to be delivered there. This needs to happen
// asynchronously, as otherwise we may end up deadlocking if the main thread calls back
// into any of the CVDisplayLink APIs.
- if (QThread::currentThread() != QGuiApplication::instance()->thread()) {
+ if (!NSThread.isMainThread) {
// We're explicitly not using the data of the GCD source to track the pending updates,
// as the data isn't reset to 0 until after the event handler, and also doesn't update
// during the event handler, both of which we need to track late frames.
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index bf0a1216be..6bedbb556d 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -1513,9 +1513,9 @@ void QCocoaWindow::deliverUpdateRequest()
void QCocoaWindow::requestActivateWindow()
{
- NSWindow *window = [m_view window];
- [window makeFirstResponder:m_view];
- [window makeKeyWindow];
+ QMacAutoReleasePool pool;
+ [m_view.window makeFirstResponder:m_view];
+ [m_view.window makeKeyWindow];
}
QCocoaNSWindow *QCocoaWindow::createNSWindow(bool shouldBePanel)
diff --git a/src/plugins/platforms/cocoa/qnswindowdelegate.mm b/src/plugins/platforms/cocoa/qnswindowdelegate.mm
index 14f1ca0114..087cb3651f 100644
--- a/src/plugins/platforms/cocoa/qnswindowdelegate.mm
+++ b/src/plugins/platforms/cocoa/qnswindowdelegate.mm
@@ -102,40 +102,6 @@ static QCocoaWindow *toPlatformWindow(NSWindow *window)
return QCocoaScreen::mapToNative(maximizedFrame);
}
-#pragma clang diagnostic push
-// NSDisableScreenUpdates and NSEnableScreenUpdates are deprecated, but the
-// NSAnimationContext API that replaces them doesn't handle the use-case of
-// cross-thread screen update synchronization.
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
-- (NSSize)windowWillResize:(NSWindow *)window toSize:(NSSize)frameSize
-{
- Q_ASSERT(toPlatformWindow(window));
-
- qCDebug(lcQpaWindow) << window << "will resize to" << QSizeF::fromCGSize(frameSize)
- << "- disabling screen updates temporarily";
-
- // There may be separate threads rendering to CA layers in this window,
- // and if any of them do a swap while the resize is still in progress,
- // the visual bounds of that layer will be updated before the visual
- // bounds of the window frame, resulting in flickering while resizing.
-
- // To prevent this we disable screen updates for the whole process until
- // the resize is complete, which makes the whole thing visually atomic.
- NSDisableScreenUpdates();
-
- return frameSize;
-}
-
-- (void)windowDidResize:(NSNotification *)notification
-{
- NSWindow *window = notification.object;
- Q_ASSERT(toPlatformWindow(window));
-
- qCDebug(lcQpaWindow) << window << "was resized - re-enabling screen updates";
- NSEnableScreenUpdates();
-}
-#pragma clang diagnostic pop
-
- (BOOL)window:(NSWindow *)window shouldPopUpDocumentPathMenu:(NSMenu *)menu
{
Q_UNUSED(menu);
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp
index 1e4f4e72c8..f154520669 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp
@@ -63,7 +63,6 @@ QEglFSKmsGbmIntegration::QEglFSKmsGbmIntegration()
#ifndef EGL_EXT_platform_base
typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETPLATFORMDISPLAYEXTPROC) (EGLenum platform, void *native_display, const EGLint *attrib_list);
-typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC) (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list);
#endif
#ifndef EGL_PLATFORM_GBM_KHR
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmwindow.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmwindow.cpp
index 65a7c4f38a..a93762e5b4 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmwindow.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmwindow.cpp
@@ -45,6 +45,10 @@
QT_BEGIN_NAMESPACE
+#ifndef EGL_EXT_platform_base
+typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC) (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list);
+#endif
+
void QEglFSKmsGbmWindow::resetSurface()
{
QEglFSKmsGbmScreen *gbmScreen = static_cast<QEglFSKmsGbmScreen *>(screen());
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index 2b96fb3a5e..41655dbd57 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -334,12 +334,8 @@ bool QWindowsContext::initTouch(unsigned integrationOptions)
if (!touchDevice)
return false;
- if (d->m_systemInfo & QWindowsContext::SI_SupportsPointer) {
- QWindowSystemInterfacePrivate::TabletEvent::setPlatformSynthesizesMouse(false);
- } else {
- if (!(integrationOptions & QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch))
- touchDevice->setCapabilities(touchDevice->capabilities() | QTouchDevice::MouseEmulation);
- }
+ if (!(integrationOptions & QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch))
+ touchDevice->setCapabilities(touchDevice->capabilities() | QTouchDevice::MouseEmulation);
QWindowSystemInterface::registerTouchDevice(touchDevice);
@@ -376,7 +372,6 @@ bool QWindowsContext::initPointer(unsigned integrationOptions)
if (!QWindowsContext::user32dll.supportsPointerApi())
return false;
- QWindowsContext::user32dll.enableMouseInPointer(TRUE);
d->m_systemInfo |= QWindowsContext::SI_SupportsPointer;
return true;
}
@@ -1218,9 +1213,10 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
case QtWindows::ExposeEvent:
return platformWindow->handleWmPaint(hwnd, message, wParam, lParam);
case QtWindows::NonClientMouseEvent:
- if (!(d->m_systemInfo & QWindowsContext::SI_SupportsPointer) && platformWindow->frameStrutEventsEnabled())
+ if ((d->m_systemInfo & QWindowsContext::SI_SupportsPointer) && platformWindow->frameStrutEventsEnabled())
+ return sessionManagerInteractionBlocked() || d->m_pointerHandler.translateMouseEvent(platformWindow->window(), hwnd, et, msg, result);
+ else
return sessionManagerInteractionBlocked() || d->m_mouseHandler.translateMouseEvent(platformWindow->window(), hwnd, et, msg, result);
- break;
case QtWindows::NonClientPointerEvent:
if ((d->m_systemInfo & QWindowsContext::SI_SupportsPointer) && platformWindow->frameStrutEventsEnabled())
return sessionManagerInteractionBlocked() || d->m_pointerHandler.translatePointerEvent(platformWindow->window(), hwnd, et, msg, result);
@@ -1246,10 +1242,10 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
window = window->parent();
if (!window)
return false;
- if (!(d->m_systemInfo & QWindowsContext::SI_SupportsPointer))
- return sessionManagerInteractionBlocked() || d->m_mouseHandler.translateMouseEvent(window, hwnd, et, msg, result);
- else
+ if (d->m_systemInfo & QWindowsContext::SI_SupportsPointer)
return sessionManagerInteractionBlocked() || d->m_pointerHandler.translateMouseEvent(window, hwnd, et, msg, result);
+ else
+ return sessionManagerInteractionBlocked() || d->m_mouseHandler.translateMouseEvent(window, hwnd, et, msg, result);
}
break;
case QtWindows::TouchEvent:
diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.cpp b/src/plugins/platforms/windows/qwindowspointerhandler.cpp
index 203d803a1b..f1960f1585 100644
--- a/src/plugins/platforms/windows/qwindowspointerhandler.cpp
+++ b/src/plugins/platforms/windows/qwindowspointerhandler.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2018 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
@@ -50,9 +50,6 @@
#include "qwindowswindow.h"
#include "qwindowsintegration.h"
#include "qwindowsscreen.h"
-#if QT_CONFIG(draganddrop)
-# include "qwindowsdrag.h"
-#endif
#include <QtGui/qguiapplication.h>
#include <QtGui/qscreen.h>
@@ -78,111 +75,9 @@ enum {
QT_PT_TOUCHPAD = 5, // MinGW is missing PT_TOUCHPAD
};
-struct PointerTouchEventInfo {
- QPointer<QWindow> window;
- QList<QWindowSystemInterface::TouchPoint> points;
- Qt::KeyboardModifiers modifiers;
-};
-
-struct PointerTabletEventInfo {
- QPointer<QWindow> window;
- QPointF local;
- QPointF global;
- int device;
- int pointerType;
- Qt::MouseButtons buttons;
- qreal pressure;
- int xTilt;
- int yTilt;
- qreal tangentialPressure;
- qreal rotation;
- int z;
- qint64 uid;
- Qt::KeyboardModifiers modifiers;
-};
-
-static QQueue<PointerTouchEventInfo> touchEventQueue;
-static QQueue<PointerTabletEventInfo> tabletEventQueue;
-
-static void enqueueTouchEvent(QWindow *window,
- const QList<QWindowSystemInterface::TouchPoint> &points,
- Qt::KeyboardModifiers modifiers)
-{
- PointerTouchEventInfo eventInfo;
- eventInfo.window = window;
- eventInfo.points = points;
- eventInfo.modifiers = modifiers;
- touchEventQueue.enqueue(eventInfo);
-}
-
-static void enqueueTabletEvent(QWindow *window, const QPointF &local, const QPointF &global,
- int device, int pointerType, Qt::MouseButtons buttons, qreal pressure,
- int xTilt, int yTilt, qreal tangentialPressure, qreal rotation,
- int z, qint64 uid, Qt::KeyboardModifiers modifiers)
-{
- PointerTabletEventInfo eventInfo;
- eventInfo.window = window;
- eventInfo.local = local;
- eventInfo.global = global;
- eventInfo.device = device;
- eventInfo.pointerType = pointerType;
- eventInfo.buttons = buttons;
- eventInfo.pressure = pressure;
- eventInfo.xTilt = xTilt;
- eventInfo.yTilt = yTilt;
- eventInfo.tangentialPressure = tangentialPressure;
- eventInfo.rotation = rotation;
- eventInfo.z = z;
- eventInfo.uid = uid;
- eventInfo.modifiers = modifiers;
- tabletEventQueue.enqueue(eventInfo);
-}
-
-static void flushTouchEvents(QTouchDevice *touchDevice)
-{
- while (!touchEventQueue.isEmpty()) {
- PointerTouchEventInfo eventInfo = touchEventQueue.dequeue();
- if (eventInfo.window) {
- QWindowSystemInterface::handleTouchEvent(eventInfo.window,
- touchDevice,
- eventInfo.points,
- eventInfo.modifiers);
- }
- }
-}
-
-static void flushTabletEvents()
-{
- while (!tabletEventQueue.isEmpty()) {
- PointerTabletEventInfo eventInfo = tabletEventQueue.dequeue();
- if (eventInfo.window) {
- QWindowSystemInterface::handleTabletEvent(eventInfo.window,
- eventInfo.local,
- eventInfo.global,
- eventInfo.device,
- eventInfo.pointerType,
- eventInfo.buttons,
- eventInfo.pressure,
- eventInfo.xTilt,
- eventInfo.yTilt,
- eventInfo.tangentialPressure,
- eventInfo.rotation,
- eventInfo.z,
- eventInfo.uid,
- eventInfo.modifiers);
- }
- }
-}
-
bool QWindowsPointerHandler::translatePointerEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, LRESULT *result)
{
*result = 0;
-
- // If we are inside the move/resize modal loop, let DefWindowProc() handle it (but process NC button release).
- QWindowsWindow *platformWindow = static_cast<QWindowsWindow *>(window->handle());
- if (msg.message != WM_NCPOINTERUP && platformWindow->testFlag(QWindowsWindow::ResizeMoveActive))
- return false;
-
const quint32 pointerId = GET_POINTERID_WPARAM(msg.wParam);
POINTER_INPUT_TYPE pointerType;
@@ -191,30 +86,12 @@ bool QWindowsPointerHandler::translatePointerEvent(QWindow *window, HWND hwnd, Q
return false;
}
- m_lastPointerType = pointerType;
-
- // Handle non-client pen/touch as generic mouse events for compatibility with QDockWindow.
- if ((pointerType == QT_PT_TOUCH || pointerType == QT_PT_PEN) && (et & QtWindows::NonClientEventFlag)) {
- POINTER_INFO pointerInfo;
- if (!QWindowsContext::user32dll.getPointerInfo(pointerId, &pointerInfo)) {
- qWarning() << "GetPointerInfo() failed:" << qt_error_string();
- return false;
- }
- if (pointerInfo.pointerFlags & (POINTER_FLAG_UP | POINTER_FLAG_DOWN))
- return translateMouseTouchPadEvent(window, hwnd, et, msg, &pointerInfo);
- return false;
- }
-
switch (pointerType) {
case QT_PT_POINTER:
case QT_PT_MOUSE:
case QT_PT_TOUCHPAD: {
- POINTER_INFO pointerInfo;
- if (!QWindowsContext::user32dll.getPointerInfo(pointerId, &pointerInfo)) {
- qWarning() << "GetPointerInfo() failed:" << qt_error_string();
- return false;
- }
- return translateMouseTouchPadEvent(window, hwnd, et, msg, &pointerInfo);
+ // Let Mouse/TouchPad be handled using legacy messages.
+ return false;
}
case QT_PT_TOUCH: {
quint32 pointerCount = 0;
@@ -290,76 +167,71 @@ bool QWindowsPointerHandler::translatePointerEvent(QWindow *window, HWND hwnd, Q
return false;
}
-static void getMouseEventInfo(UINT message, POINTER_BUTTON_CHANGE_TYPE changeType, QEvent::Type *eventType, Qt::MouseButton *mouseButton)
-{
- static const QHash<POINTER_BUTTON_CHANGE_TYPE, Qt::MouseButton> buttonMapping {
- {POINTER_CHANGE_FIRSTBUTTON_DOWN, Qt::LeftButton},
- {POINTER_CHANGE_FIRSTBUTTON_UP, Qt::LeftButton},
- {POINTER_CHANGE_SECONDBUTTON_DOWN, Qt::RightButton},
- {POINTER_CHANGE_SECONDBUTTON_UP, Qt::RightButton},
- {POINTER_CHANGE_THIRDBUTTON_DOWN, Qt::MiddleButton},
- {POINTER_CHANGE_THIRDBUTTON_UP, Qt::MiddleButton},
- {POINTER_CHANGE_FOURTHBUTTON_DOWN, Qt::XButton1},
- {POINTER_CHANGE_FOURTHBUTTON_UP, Qt::XButton1},
- {POINTER_CHANGE_FIFTHBUTTON_DOWN, Qt::XButton2},
- {POINTER_CHANGE_FIFTHBUTTON_UP, Qt::XButton2},
- };
-
- static const POINTER_BUTTON_CHANGE_TYPE downChanges[] = {
- POINTER_CHANGE_FIRSTBUTTON_DOWN,
- POINTER_CHANGE_SECONDBUTTON_DOWN,
- POINTER_CHANGE_THIRDBUTTON_DOWN,
- POINTER_CHANGE_FOURTHBUTTON_DOWN,
- POINTER_CHANGE_FIFTHBUTTON_DOWN,
- };
-
- static const POINTER_BUTTON_CHANGE_TYPE upChanges[] = {
- POINTER_CHANGE_FIRSTBUTTON_UP,
- POINTER_CHANGE_SECONDBUTTON_UP,
- POINTER_CHANGE_THIRDBUTTON_UP,
- POINTER_CHANGE_FOURTHBUTTON_UP,
- POINTER_CHANGE_FIFTHBUTTON_UP,
- };
-
- if (!eventType || !mouseButton)
- return;
-
- const bool nonClient = message == WM_NCPOINTERUPDATE ||
- message == WM_NCPOINTERDOWN ||
- message == WM_NCPOINTERUP;
-
- if (std::find(std::begin(downChanges),
- std::end(downChanges), changeType) < std::end(downChanges)) {
- *eventType = nonClient ? QEvent::NonClientAreaMouseButtonPress :
- QEvent::MouseButtonPress;
- } else if (std::find(std::begin(upChanges),
- std::end(upChanges), changeType) < std::end(upChanges)) {
- *eventType = nonClient ? QEvent::NonClientAreaMouseButtonRelease :
- QEvent::MouseButtonRelease;
- } else if (message == WM_POINTERWHEEL || message == WM_POINTERHWHEEL) {
- *eventType = QEvent::Wheel;
- } else {
- *eventType = nonClient ? QEvent::NonClientAreaMouseMove :
- QEvent::MouseMove;
- }
+namespace {
+struct MouseEvent {
+ QEvent::Type type;
+ Qt::MouseButton button;
+};
+} // namespace
- *mouseButton = buttonMapping.value(changeType, Qt::NoButton);
+static inline Qt::MouseButton extraButton(WPARAM wParam) // for WM_XBUTTON...
+{
+ return GET_XBUTTON_WPARAM(wParam) == XBUTTON1 ? Qt::BackButton : Qt::ForwardButton;
}
-static Qt::MouseButtons mouseButtonsFromPointerFlags(POINTER_FLAGS pointerFlags)
+static inline MouseEvent eventFromMsg(const MSG &msg)
{
- Qt::MouseButtons result = Qt::NoButton;
- if (pointerFlags & POINTER_FLAG_FIRSTBUTTON)
- result |= Qt::LeftButton;
- if (pointerFlags & POINTER_FLAG_SECONDBUTTON)
- result |= Qt::RightButton;
- if (pointerFlags & POINTER_FLAG_THIRDBUTTON)
- result |= Qt::MiddleButton;
- if (pointerFlags & POINTER_FLAG_FOURTHBUTTON)
- result |= Qt::XButton1;
- if (pointerFlags & POINTER_FLAG_FIFTHBUTTON)
- result |= Qt::XButton2;
- return result;
+ switch (msg.message) {
+ case WM_MOUSEMOVE:
+ return {QEvent::MouseMove, Qt::NoButton};
+ case WM_LBUTTONDOWN:
+ return {QEvent::MouseButtonPress, Qt::LeftButton};
+ case WM_LBUTTONUP:
+ return {QEvent::MouseButtonRelease, Qt::LeftButton};
+ case WM_LBUTTONDBLCLK: // Qt QPA does not handle double clicks, send as press
+ return {QEvent::MouseButtonPress, Qt::LeftButton};
+ case WM_MBUTTONDOWN:
+ return {QEvent::MouseButtonPress, Qt::MidButton};
+ case WM_MBUTTONUP:
+ return {QEvent::MouseButtonRelease, Qt::MidButton};
+ case WM_MBUTTONDBLCLK:
+ return {QEvent::MouseButtonPress, Qt::MidButton};
+ case WM_RBUTTONDOWN:
+ return {QEvent::MouseButtonPress, Qt::RightButton};
+ case WM_RBUTTONUP:
+ return {QEvent::MouseButtonRelease, Qt::RightButton};
+ case WM_RBUTTONDBLCLK:
+ return {QEvent::MouseButtonPress, Qt::RightButton};
+ case WM_XBUTTONDOWN:
+ return {QEvent::MouseButtonPress, extraButton(msg.wParam)};
+ case WM_XBUTTONUP:
+ return {QEvent::MouseButtonRelease, extraButton(msg.wParam)};
+ case WM_XBUTTONDBLCLK:
+ return {QEvent::MouseButtonPress, extraButton(msg.wParam)};
+ case WM_NCMOUSEMOVE:
+ return {QEvent::NonClientAreaMouseMove, Qt::NoButton};
+ case WM_NCLBUTTONDOWN:
+ return {QEvent::NonClientAreaMouseButtonPress, Qt::LeftButton};
+ case WM_NCLBUTTONUP:
+ return {QEvent::NonClientAreaMouseButtonRelease, Qt::LeftButton};
+ case WM_NCLBUTTONDBLCLK:
+ return {QEvent::NonClientAreaMouseButtonPress, Qt::LeftButton};
+ case WM_NCMBUTTONDOWN:
+ return {QEvent::NonClientAreaMouseButtonPress, Qt::MidButton};
+ case WM_NCMBUTTONUP:
+ return {QEvent::NonClientAreaMouseButtonRelease, Qt::MidButton};
+ case WM_NCMBUTTONDBLCLK:
+ return {QEvent::NonClientAreaMouseButtonPress, Qt::MidButton};
+ case WM_NCRBUTTONDOWN:
+ return {QEvent::NonClientAreaMouseButtonPress, Qt::RightButton};
+ case WM_NCRBUTTONUP:
+ return {QEvent::NonClientAreaMouseButtonRelease, Qt::RightButton};
+ case WM_NCRBUTTONDBLCLK:
+ return {QEvent::NonClientAreaMouseButtonPress, Qt::RightButton};
+ default: // WM_MOUSELEAVE
+ break;
+ }
+ return {QEvent::None, Qt::NoButton};
}
static Qt::MouseButtons mouseButtonsFromKeyState(WPARAM keyState)
@@ -419,15 +291,6 @@ static bool isValidWheelReceiver(QWindow *candidate)
return false;
}
-static bool isMenuWindow(QWindow *window)
-{
- if (window)
- if (QObject *fo = window->focusObject())
- if (fo->inherits("QMenu"))
- return true;
- return false;
-}
-
static QTouchDevice *createTouchDevice()
{
const int digitizers = GetSystemMetrics(SM_DIGITIZER);
@@ -553,71 +416,6 @@ void QWindowsPointerHandler::handleEnterLeave(QWindow *window,
m_previousCaptureWindow = hasCapture ? window : nullptr;
}
-bool QWindowsPointerHandler::translateMouseTouchPadEvent(QWindow *window, HWND hwnd,
- QtWindows::WindowsEventType et,
- MSG msg, PVOID vPointerInfo)
-{
- POINTER_INFO *pointerInfo = static_cast<POINTER_INFO *>(vPointerInfo);
- const QPoint globalPos = QPoint(pointerInfo->ptPixelLocation.x, pointerInfo->ptPixelLocation.y);
- const QPoint localPos = QWindowsGeometryHint::mapFromGlobal(hwnd, globalPos);
- const Qt::KeyboardModifiers keyModifiers = QWindowsKeyMapper::queryKeyboardModifiers();
- const Qt::MouseButtons mouseButtons = mouseButtonsFromPointerFlags(pointerInfo->pointerFlags);
- QWindow *currentWindowUnderPointer = getWindowUnderPointer(window, globalPos);
-
- switch (msg.message) {
- case WM_NCPOINTERDOWN:
- case WM_NCPOINTERUP:
- case WM_NCPOINTERUPDATE:
- case WM_POINTERDOWN:
- case WM_POINTERUP:
- case WM_POINTERUPDATE: {
-
- QEvent::Type eventType;
- Qt::MouseButton button;
- getMouseEventInfo(msg.message, pointerInfo->ButtonChangeType, &eventType, &button);
-
- if (et & QtWindows::NonClientEventFlag) {
- QWindowSystemInterface::handleFrameStrutMouseEvent(window, localPos, globalPos, mouseButtons, button, eventType,
- keyModifiers, Qt::MouseEventNotSynthesized);
- return false; // To allow window dragging, etc.
- } else {
-
- handleCaptureRelease(window, currentWindowUnderPointer, hwnd, eventType, mouseButtons);
- handleEnterLeave(window, currentWindowUnderPointer, globalPos);
-
- QWindowSystemInterface::handleMouseEvent(window, localPos, globalPos, mouseButtons, button, eventType,
- keyModifiers, Qt::MouseEventNotSynthesized);
-
- // The initial down click over the QSizeGrip area, which posts a resize WM_SYSCOMMAND
- // has go to through DefWindowProc() for resizing to work, so we return false here,
- // unless the click was on a menu, as it would mess with menu processing.
- return msg.message != WM_POINTERDOWN || isMenuWindow(window);
- }
- }
- case WM_POINTERHWHEEL:
- case WM_POINTERWHEEL: {
-
- if (!isValidWheelReceiver(window))
- return true;
-
- int delta = GET_WHEEL_DELTA_WPARAM(msg.wParam);
-
- // Qt horizontal wheel rotation orientation is opposite to the one in WM_POINTERHWHEEL
- if (msg.message == WM_POINTERHWHEEL)
- delta = -delta;
-
- const QPoint angleDelta = (msg.message == WM_POINTERHWHEEL || (keyModifiers & Qt::AltModifier)) ?
- QPoint(delta, 0) : QPoint(0, delta);
-
- QWindowSystemInterface::handleWheelEvent(window, localPos, globalPos, QPoint(), angleDelta, keyModifiers);
- return true;
- }
- case WM_POINTERLEAVE:
- return true;
- }
- return false;
-}
-
bool QWindowsPointerHandler::translateTouchEvent(QWindow *window, HWND hwnd,
QtWindows::WindowsEventType et,
MSG msg, PVOID vTouchInfo, quint32 count)
@@ -653,15 +451,14 @@ bool QWindowsPointerHandler::translateTouchEvent(QWindow *window, HWND hwnd,
QList<QWindowSystemInterface::TouchPoint> touchPoints;
- bool primaryPointer = false;
- bool pressRelease = false;
-
if (QWindowsContext::verbose > 1)
qCDebug(lcQpaEvents).noquote().nospace() << showbase
<< __FUNCTION__
<< " message=" << hex << msg.message
<< " count=" << dec << count;
+ Qt::TouchPointStates allStates = 0;
+
for (quint32 i = 0; i < count; ++i) {
if (QWindowsContext::verbose > 1)
qCDebug(lcQpaEvents).noquote().nospace() << showbase
@@ -670,7 +467,13 @@ bool QWindowsPointerHandler::translateTouchEvent(QWindow *window, HWND hwnd,
<< " flags=" << hex << touchInfo[i].pointerInfo.pointerFlags;
QWindowSystemInterface::TouchPoint touchPoint;
- touchPoint.id = touchInfo[i].pointerInfo.pointerId;
+ const quint32 pointerId = touchInfo[i].pointerInfo.pointerId;
+ int id = m_touchInputIDToTouchPointID.value(pointerId, -1);
+ if (id == -1) {
+ id = m_touchInputIDToTouchPointID.size();
+ m_touchInputIDToTouchPointID.insert(pointerId, id);
+ }
+ touchPoint.id = id;
touchPoint.pressure = (touchInfo[i].touchMask & TOUCH_MASK_PRESSURE) ?
touchInfo[i].pressure / 1024.0 : 1.0;
if (m_lastTouchPositions.contains(touchPoint.id))
@@ -691,32 +494,27 @@ bool QWindowsPointerHandler::translateTouchEvent(QWindow *window, HWND hwnd,
if (touchInfo[i].pointerInfo.pointerFlags & POINTER_FLAG_DOWN) {
touchPoint.state = Qt::TouchPointPressed;
m_lastTouchPositions.insert(touchPoint.id, touchPoint.normalPosition);
- pressRelease = true;
} else if (touchInfo[i].pointerInfo.pointerFlags & POINTER_FLAG_UP) {
touchPoint.state = Qt::TouchPointReleased;
m_lastTouchPositions.remove(touchPoint.id);
- pressRelease = true;
} else {
touchPoint.state = stationaryTouchPoint ? Qt::TouchPointStationary : Qt::TouchPointMoved;
m_lastTouchPositions.insert(touchPoint.id, touchPoint.normalPosition);
}
- if (touchInfo[i].pointerInfo.pointerFlags & POINTER_FLAG_PRIMARY)
- primaryPointer = true;
+ allStates |= touchPoint.state;
touchPoints.append(touchPoint);
// Avoid getting repeated messages for this frame if there are multiple pointerIds
QWindowsContext::user32dll.skipPointerFrameMessages(touchInfo[i].pointerInfo.pointerId);
}
- if (primaryPointer && !pressRelease) {
- // Postpone event delivery to avoid hanging inside DoDragDrop().
- // Only the primary pointer will generate mouse messages.
- enqueueTouchEvent(window, touchPoints, QWindowsKeyMapper::queryKeyboardModifiers());
- } else {
- flushTouchEvents(m_touchDevice);
- QWindowSystemInterface::handleTouchEvent(window, m_touchDevice, touchPoints,
- QWindowsKeyMapper::queryKeyboardModifiers());
- }
+
+ // all touch points released, forget the ids we've seen.
+ if (allStates == Qt::TouchPointReleased)
+ m_touchInputIDToTouchPointID.clear();
+
+ QWindowSystemInterface::handleTouchEvent(window, m_touchDevice, touchPoints,
+ QWindowsKeyMapper::queryKeyboardModifiers());
return false; // Allow mouse messages to be generated.
}
@@ -807,10 +605,9 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin
}
const Qt::KeyboardModifiers keyModifiers = QWindowsKeyMapper::queryKeyboardModifiers();
- // Postpone event delivery to avoid hanging inside DoDragDrop().
- enqueueTabletEvent(target, localPos, hiResGlobalPos, device, type, mouseButtons,
- pressure, xTilt, yTilt, tangentialPressure, rotation, z,
- pointerId, keyModifiers);
+ QWindowSystemInterface::handleTabletEvent(target, localPos, hiResGlobalPos, device, type, mouseButtons,
+ pressure, xTilt, yTilt, tangentialPressure, rotation, z,
+ pointerId, keyModifiers);
return false; // Allow mouse messages to be generated.
}
}
@@ -835,18 +632,46 @@ static inline bool isMouseEventSynthesizedFromPenOrTouch()
return ((::GetMessageExtraInfo() & SIGNATURE_MASK) == MI_WP_SIGNATURE);
}
-// Process old-style mouse messages here.
-bool QWindowsPointerHandler::translateMouseEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, LRESULT *result)
+bool QWindowsPointerHandler::translateMouseWheelEvent(QWindow *window,
+ QWindow *currentWindowUnderPointer,
+ MSG msg,
+ QPoint globalPos,
+ Qt::KeyboardModifiers keyModifiers)
{
- // Generate enqueued events.
- flushTouchEvents(m_touchDevice);
- flushTabletEvents();
+ QWindow *receiver = currentWindowUnderPointer;
+ if (!isValidWheelReceiver(receiver))
+ receiver = window;
+ if (!isValidWheelReceiver(receiver))
+ return true;
+
+ int delta = GET_WHEEL_DELTA_WPARAM(msg.wParam);
+ // Qt horizontal wheel rotation orientation is opposite to the one in WM_MOUSEHWHEEL
+ if (msg.message == WM_MOUSEHWHEEL)
+ delta = -delta;
+
+ const QPoint angleDelta = (msg.message == WM_MOUSEHWHEEL || (keyModifiers & Qt::AltModifier)) ?
+ QPoint(delta, 0) : QPoint(0, delta);
+
+ QPoint localPos = QWindowsGeometryHint::mapFromGlobal(receiver, globalPos);
+
+ QWindowSystemInterface::handleWheelEvent(window, localPos, globalPos, QPoint(), angleDelta, keyModifiers);
+ return true;
+}
+
+// Process legacy mouse messages here.
+bool QWindowsPointerHandler::translateMouseEvent(QWindow *window,
+ HWND hwnd,
+ QtWindows::WindowsEventType et,
+ MSG msg,
+ LRESULT *result)
+{
*result = 0;
const QPoint eventPos(GET_X_LPARAM(msg.lParam), GET_Y_LPARAM(msg.lParam));
QPoint localPos;
QPoint globalPos;
+
if ((et == QtWindows::MouseWheelEvent) || (et & QtWindows::NonClientEventFlag)) {
globalPos = eventPos;
localPos = QWindowsGeometryHint::mapFromGlobal(hwnd, eventPos);
@@ -857,46 +682,39 @@ bool QWindowsPointerHandler::translateMouseEvent(QWindow *window, HWND hwnd, QtW
const Qt::KeyboardModifiers keyModifiers = QWindowsKeyMapper::queryKeyboardModifiers();
const Qt::MouseButtons mouseButtons = mouseButtonsFromKeyState(msg.wParam);
+ QWindow *currentWindowUnderPointer = getWindowUnderPointer(window, globalPos);
- // Handle "press and hold for right-clicking".
- // We have to synthesize it here as it only comes from Windows as a fake RMB.
- // MS docs say we could use bit 7 from extraInfo to distinguish pen from touch,
- // but on the Surface it is set for both. So we use the last pointer type.
- if (isMouseEventSynthesizedFromPenOrTouch()) {
- if ((msg.message == WM_RBUTTONDOWN || msg.message == WM_RBUTTONUP)
- && (((m_lastPointerType == QT_PT_PEN)
- && QCoreApplication::testAttribute(Qt::AA_SynthesizeMouseForUnhandledTabletEvents))
- || ((m_lastPointerType == QT_PT_TOUCH)
- && QCoreApplication::testAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents)))) {
- QWindowSystemInterface::handleMouseEvent(window, localPos, globalPos, mouseButtons, Qt::RightButton,
- (msg.message == WM_RBUTTONDOWN) ? QEvent::MouseButtonPress
- : QEvent::MouseButtonRelease,
- keyModifiers, Qt::MouseEventSynthesizedBySystem);
- }
- // Messages synthesized from touch/pen are only used for flushing queues and press&hold.
- return false;
+ if (et == QtWindows::MouseWheelEvent)
+ return translateMouseWheelEvent(window, currentWindowUnderPointer, msg, globalPos, keyModifiers);
+
+ // Windows sends a mouse move with no buttons pressed to signal "Enter"
+ // when a window is shown over the cursor. Discard the event and only use
+ // it for generating QEvent::Enter to be consistent with other platforms -
+ // X11 and macOS.
+ bool discardEvent = false;
+ if (msg.message == WM_MOUSEMOVE) {
+ static QPoint lastMouseMovePos;
+ if (msg.wParam == 0 && (m_windowUnderPointer.isNull() || globalPos == lastMouseMovePos))
+ discardEvent = true;
+ lastMouseMovePos = globalPos;
}
- if (et == QtWindows::MouseWheelEvent) {
-
- if (!isValidWheelReceiver(window))
- return true;
-
- int delta = GET_WHEEL_DELTA_WPARAM(msg.wParam);
-
- // Qt horizontal wheel rotation orientation is opposite to the one in WM_MOUSEHWHEEL
- if (msg.message == WM_MOUSEHWHEEL)
- delta = -delta;
+ Qt::MouseEventSource source = Qt::MouseEventNotSynthesized;
+ if (isMouseEventSynthesizedFromPenOrTouch()) {
+ if (QWindowsIntegration::instance()->options() & QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch)
+ return false;
+ source = Qt::MouseEventSynthesizedBySystem;
+ }
- const QPoint angleDelta = (msg.message == WM_MOUSEHWHEEL || (keyModifiers & Qt::AltModifier)) ?
- QPoint(delta, 0) : QPoint(0, delta);
+ const MouseEvent mouseEvent = eventFromMsg(msg);
- QWindowSystemInterface::handleWheelEvent(window, localPos, globalPos, QPoint(), angleDelta, keyModifiers);
- return true;
+ if (mouseEvent.type >= QEvent::NonClientAreaMouseMove && mouseEvent.type <= QEvent::NonClientAreaMouseButtonDblClick) {
+ QWindowSystemInterface::handleFrameStrutMouseEvent(window, localPos, globalPos, mouseButtons,
+ mouseEvent.button, mouseEvent.type, keyModifiers, source);
+ return false; // Allow further event processing
}
if (msg.message == WM_MOUSELEAVE) {
-
if (window == m_currentWindow) {
QWindow *leaveTarget = m_windowUnderPointer ? m_windowUnderPointer : m_currentWindow;
qCDebug(lcQpaEvents) << "Leaving window " << leaveTarget;
@@ -904,14 +722,21 @@ bool QWindowsPointerHandler::translateMouseEvent(QWindow *window, HWND hwnd, QtW
m_windowUnderPointer = nullptr;
m_currentWindow = nullptr;
}
+ return true;
+ }
- } else if (msg.message == WM_MOUSEMOVE) {
+ handleCaptureRelease(window, currentWindowUnderPointer, hwnd, mouseEvent.type, mouseButtons);
+ handleEnterLeave(window, currentWindowUnderPointer, globalPos);
- QWindow *currentWindowUnderPointer = getWindowUnderPointer(window, globalPos);
- handleCaptureRelease(window, currentWindowUnderPointer, hwnd, QEvent::MouseMove, mouseButtons);
- handleEnterLeave(window, currentWindowUnderPointer, globalPos);
+ if (!discardEvent && mouseEvent.type != QEvent::None) {
+ QWindowSystemInterface::handleMouseEvent(window, localPos, globalPos, mouseButtons,
+ mouseEvent.button, mouseEvent.type, keyModifiers, source);
}
- return false;
+
+ // 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();
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.h b/src/plugins/platforms/windows/qwindowspointerhandler.h
index ec3179e821..aebef062bc 100644
--- a/src/plugins/platforms/windows/qwindowspointerhandler.h
+++ b/src/plugins/platforms/windows/qwindowspointerhandler.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2018 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
@@ -66,19 +66,19 @@ public:
void clearWindowUnderMouse() { m_windowUnderPointer = nullptr; }
private:
- bool translateMouseTouchPadEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, PVOID vPointerInfo);
bool translateTouchEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, PVOID vTouchInfo, unsigned int count);
bool translatePenEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, PVOID vPenInfo);
+ bool translateMouseWheelEvent(QWindow *window, QWindow *currentWindowUnderPointer, MSG msg, QPoint globalPos, Qt::KeyboardModifiers keyModifiers);
void handleCaptureRelease(QWindow *window, QWindow *currentWindowUnderPointer, HWND hwnd, QEvent::Type eventType, Qt::MouseButtons mouseButtons);
void handleEnterLeave(QWindow *window, QWindow *currentWindowUnderPointer, QPoint globalPos);
QTouchDevice *m_touchDevice = nullptr;
QHash<int, QPointF> m_lastTouchPositions;
+ QHash<DWORD, int> m_touchInputIDToTouchPointID;
QPointer<QWindow> m_windowUnderPointer;
QPointer<QWindow> m_currentWindow;
QWindow *m_previousCaptureWindow = nullptr;
bool m_needsEnterOnPointerUpdate = false;
- DWORD m_lastPointerType = 0;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp
index 7f1854c601..e611c7be24 100644
--- a/src/plugins/platforms/winrt/qwinrtscreen.cpp
+++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp
@@ -511,6 +511,7 @@ public:
QWindow *currentPressWindow = nullptr;
QWindow *currentTargetWindow = nullptr;
bool firstMouseMove = true;
+ bool resizePending = false;
};
// To be called from the XAML thread
@@ -1402,6 +1403,18 @@ void QWinRTScreen::emulateMouseMove(const QPointF &point, MousePositionTransitio
Qt::NoModifier);
}
+void QWinRTScreen::setResizePending()
+{
+ Q_D(QWinRTScreen);
+ d->resizePending = true;
+}
+
+bool QWinRTScreen::resizePending() const
+{
+ Q_D(const QWinRTScreen);
+ return d->resizePending;
+}
+
HRESULT QWinRTScreen::onActivated(ICoreWindow *, IWindowActivatedEventArgs *args)
{
Q_D(QWinRTScreen);
@@ -1507,7 +1520,7 @@ HRESULT QWinRTScreen::onRedirectReleased(ICorePointerRedirector *, IPointerEvent
return onPointerUpdated(nullptr, args);
}
-HRESULT QWinRTScreen::onWindowSizeChanged(IApplicationView *, IInspectable *)
+HRESULT QWinRTScreen::onWindowSizeChanged(IApplicationView *w, IInspectable *)
{
Q_D(QWinRTScreen);
@@ -1527,6 +1540,9 @@ HRESULT QWinRTScreen::onWindowSizeChanged(IApplicationView *, IInspectable *)
QWindowSystemInterface::handleScreenGeometryChange(screen(), geometry(), availableGeometry());
QPlatformScreen::resizeMaximizedWindows();
handleExpose();
+ // If we "emulate" a resize, w will be nullptr.Checking w shows whether it's a real resize
+ if (w)
+ d->resizePending = false;
return S_OK;
}
diff --git a/src/plugins/platforms/winrt/qwinrtscreen.h b/src/plugins/platforms/winrt/qwinrtscreen.h
index e28cfd8cc8..63c254940d 100644
--- a/src/plugins/platforms/winrt/qwinrtscreen.h
+++ b/src/plugins/platforms/winrt/qwinrtscreen.h
@@ -136,6 +136,9 @@ public:
void emulateMouseMove(const QPointF &point, MousePositionTransition transition);
+ void setResizePending();
+ bool resizePending() const;
+
private:
void handleExpose();
diff --git a/src/plugins/platforms/winrt/qwinrtwindow.cpp b/src/plugins/platforms/winrt/qwinrtwindow.cpp
index 83c3715bfd..73816b6512 100644
--- a/src/plugins/platforms/winrt/qwinrtwindow.cpp
+++ b/src/plugins/platforms/winrt/qwinrtwindow.cpp
@@ -225,7 +225,8 @@ bool QWinRTWindow::isActive() const
bool QWinRTWindow::isExposed() const
{
- const bool exposed = isActive();
+ Q_D(const QWinRTWindow);
+ const bool exposed = isActive() && !d->screen->resizePending();
return exposed;
}
@@ -360,6 +361,7 @@ void QWinRTWindow::setWindowState(Qt::WindowStates state)
qCDebug(lcQpaWindows) << "Failed to enter full screen mode.";
return;
}
+ d->screen->setResizePending();
d->state = state;
return;
}
@@ -384,6 +386,7 @@ void QWinRTWindow::setWindowState(Qt::WindowStates state)
qCDebug(lcQpaWindows) << "Failed to exit full screen mode.";
return;
}
+ d->screen->setResizePending();
}
if (d->state & Qt::WindowMinimized || state == Qt::WindowNoState || state == Qt::WindowActive)
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index b91d637766..6a5f80f1ff 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -8298,49 +8298,57 @@ void QWidgetPrivate::hide_sys()
\endlist
*/
-
void QWidget::setVisible(bool visible)
{
- if (visible) { // show
- if (testAttribute(Qt::WA_WState_ExplicitShowHide) && !testAttribute(Qt::WA_WState_Hidden))
- return;
+ if (testAttribute(Qt::WA_WState_ExplicitShowHide) && testAttribute(Qt::WA_WState_Hidden) == !visible)
+ return;
- Q_D(QWidget);
+ // Remember that setVisible was called explicitly
+ setAttribute(Qt::WA_WState_ExplicitShowHide);
+
+ Q_D(QWidget);
+ d->setVisible(visible);
+}
+// This method is called from QWidgetWindow in response to QWindow::setVisible,
+// and should match the semantics of QWindow::setVisible. QWidget::setVisible on
+// the other hand keeps track of WA_WState_ExplicitShowHide in addition.
+void QWidgetPrivate::setVisible(bool visible)
+{
+ Q_Q(QWidget);
+ if (visible) { // show
// Designer uses a trick to make grabWidget work without showing
- if (!isWindow() && parentWidget() && parentWidget()->isVisible()
- && !parentWidget()->testAttribute(Qt::WA_WState_Created))
- parentWidget()->window()->d_func()->createRecursively();
+ if (!q->isWindow() && q->parentWidget() && q->parentWidget()->isVisible()
+ && !q->parentWidget()->testAttribute(Qt::WA_WState_Created))
+ q->parentWidget()->window()->d_func()->createRecursively();
//create toplevels but not children of non-visible parents
- QWidget *pw = parentWidget();
- if (!testAttribute(Qt::WA_WState_Created)
- && (isWindow() || pw->testAttribute(Qt::WA_WState_Created))) {
- create();
+ QWidget *pw = q->parentWidget();
+ if (!q->testAttribute(Qt::WA_WState_Created)
+ && (q->isWindow() || pw->testAttribute(Qt::WA_WState_Created))) {
+ q->create();
}
- bool wasResized = testAttribute(Qt::WA_Resized);
- Qt::WindowStates initialWindowState = windowState();
+ bool wasResized = q->testAttribute(Qt::WA_Resized);
+ Qt::WindowStates initialWindowState = q->windowState();
// polish if necessary
- ensurePolished();
+ q->ensurePolished();
- // remember that show was called explicitly
- setAttribute(Qt::WA_WState_ExplicitShowHide);
// whether we need to inform the parent widget immediately
- bool needUpdateGeometry = !isWindow() && testAttribute(Qt::WA_WState_Hidden);
+ bool needUpdateGeometry = !q->isWindow() && q->testAttribute(Qt::WA_WState_Hidden);
// we are no longer hidden
- setAttribute(Qt::WA_WState_Hidden, false);
+ q->setAttribute(Qt::WA_WState_Hidden, false);
if (needUpdateGeometry)
- d->updateGeometry_helper(true);
+ updateGeometry_helper(true);
// activate our layout before we and our children become visible
- if (d->layout)
- d->layout->activate();
+ if (layout)
+ layout->activate();
- if (!isWindow()) {
- QWidget *parent = parentWidget();
+ if (!q->isWindow()) {
+ QWidget *parent = q->parentWidget();
while (parent && parent->isVisible() && parent->d_func()->layout && !parent->data->in_show) {
parent->d_func()->layout->activate();
if (parent->isWindow())
@@ -8353,30 +8361,28 @@ void QWidget::setVisible(bool visible)
// adjust size if necessary
if (!wasResized
- && (isWindow() || !parentWidget()->d_func()->layout)) {
- if (isWindow()) {
- adjustSize();
- if (windowState() != initialWindowState)
- setWindowState(initialWindowState);
+ && (q->isWindow() || !q->parentWidget()->d_func()->layout)) {
+ if (q->isWindow()) {
+ q->adjustSize();
+ if (q->windowState() != initialWindowState)
+ q->setWindowState(initialWindowState);
} else {
- adjustSize();
+ q->adjustSize();
}
- setAttribute(Qt::WA_Resized, false);
+ q->setAttribute(Qt::WA_Resized, false);
}
- setAttribute(Qt::WA_KeyboardFocusChange, false);
+ q->setAttribute(Qt::WA_KeyboardFocusChange, false);
- if (isWindow() || parentWidget()->isVisible()) {
- d->show_helper();
+ if (q->isWindow() || q->parentWidget()->isVisible()) {
+ show_helper();
- qApp->d_func()->sendSyntheticEnterLeave(this);
+ qApp->d_func()->sendSyntheticEnterLeave(q);
}
QEvent showToParentEvent(QEvent::ShowToParent);
- QApplication::sendEvent(this, &showToParentEvent);
+ QApplication::sendEvent(q, &showToParentEvent);
} else { // hide
- if (testAttribute(Qt::WA_WState_ExplicitShowHide) && testAttribute(Qt::WA_WState_Hidden))
- return;
#if 0 // Used to be included in Qt4 for Q_WS_WIN
// reset WS_DISABLED style in a Blocked window
if(isWindow() && testAttribute(Qt::WA_WState_Created)
@@ -8387,33 +8393,30 @@ void QWidget::setVisible(bool visible)
SetWindowLong(winId(), GWL_STYLE, dwStyle);
}
#endif
- if (QApplicationPrivate::hidden_focus_widget == this)
+ if (QApplicationPrivate::hidden_focus_widget == q)
QApplicationPrivate::hidden_focus_widget = 0;
- Q_D(QWidget);
-
// hw: The test on getOpaqueRegion() needs to be more intelligent
// currently it doesn't work if the widget is hidden (the region will
// be clipped). The real check should be testing the cached region
// (and dirty flag) directly.
- if (!isWindow() && parentWidget()) // && !d->getOpaqueRegion().isEmpty())
- parentWidget()->d_func()->setDirtyOpaqueRegion();
+ if (!q->isWindow() && q->parentWidget()) // && !d->getOpaqueRegion().isEmpty())
+ q->parentWidget()->d_func()->setDirtyOpaqueRegion();
- setAttribute(Qt::WA_WState_Hidden);
- setAttribute(Qt::WA_WState_ExplicitShowHide);
- if (testAttribute(Qt::WA_WState_Created))
- d->hide_helper();
+ q->setAttribute(Qt::WA_WState_Hidden);
+ if (q->testAttribute(Qt::WA_WState_Created))
+ hide_helper();
// invalidate layout similar to updateGeometry()
- if (!isWindow() && parentWidget()) {
- if (parentWidget()->d_func()->layout)
- parentWidget()->d_func()->layout->invalidate();
- else if (parentWidget()->isVisible())
- QApplication::postEvent(parentWidget(), new QEvent(QEvent::LayoutRequest));
+ if (!q->isWindow() && q->parentWidget()) {
+ if (q->parentWidget()->d_func()->layout)
+ q->parentWidget()->d_func()->layout->invalidate();
+ else if (q->parentWidget()->isVisible())
+ QApplication::postEvent(q->parentWidget(), new QEvent(QEvent::LayoutRequest));
}
QEvent hideToParentEvent(QEvent::HideToParent);
- QApplication::sendEvent(this, &hideToParentEvent);
+ QApplication::sendEvent(q, &hideToParentEvent);
}
}
diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h
index e50d828775..797963b931 100644
--- a/src/widgets/kernel/qwidget_p.h
+++ b/src/widgets/kernel/qwidget_p.h
@@ -485,6 +485,7 @@ public:
void hide_sys();
void hide_helper();
void _q_showIfNotHidden();
+ void setVisible(bool);
void setEnabled_helper(bool);
static void adjustFlags(Qt::WindowFlags &flags, QWidget *w = 0);
diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp
index 991a05fa02..e9b749d7c2 100644
--- a/src/widgets/kernel/qwidgetwindow.cpp
+++ b/src/widgets/kernel/qwidgetwindow.cpp
@@ -73,7 +73,7 @@ public:
{
Q_Q(QWidgetWindow);
if (QWidget *widget = q->widget())
- widget->setVisible(visible);
+ QWidgetPrivate::get(widget)->setVisible(visible);
else
QWindowPrivate::setVisible(visible);
}
diff --git a/src/widgets/widgets/qcalendarwidget.cpp b/src/widgets/widgets/qcalendarwidget.cpp
index 7637877926..47c5267c73 100644
--- a/src/widgets/widgets/qcalendarwidget.cpp
+++ b/src/widgets/widgets/qcalendarwidget.cpp
@@ -3064,19 +3064,22 @@ bool QCalendarWidget::eventFilter(QObject *watched, QEvent *event)
{
Q_D(QCalendarWidget);
if (event->type() == QEvent::MouseButtonPress && d->yearEdit->hasFocus()) {
+ // We can get filtered press events that were intended for Qt Virtual Keyboard's
+ // input panel (QQuickView), so we have to make sure that the window is indeed a QWidget - no static_cast.
+ // In addition, as we have a event filter on the whole application we first make sure that the top level widget
+ // of both this and the watched widget are the same to decide if we should finish the year edition.
QWidget *tlw = window();
- QWidget *widget = static_cast<QWidget*>(watched);
- //as we have a event filter on the whole application we first make sure that the top level widget
- //of both this and the watched widget are the same to decide if we should finish the year edition.
- if (widget->window() == tlw) {
- QPoint mousePos = widget->mapTo(tlw, static_cast<QMouseEvent *>(event)->pos());
- QRect geom = QRect(d->yearEdit->mapTo(tlw, QPoint(0, 0)), d->yearEdit->size());
- if (!geom.contains(mousePos)) {
- event->accept();
- d->_q_yearEditingFinished();
- setFocus();
- return true;
- }
+ QWidget *widget = qobject_cast<QWidget *>(watched);
+ if (!widget || widget->window() != tlw)
+ return QWidget::eventFilter(watched, event);
+
+ QPoint mousePos = widget->mapTo(tlw, static_cast<QMouseEvent *>(event)->pos());
+ QRect geom = QRect(d->yearEdit->mapTo(tlw, QPoint(0, 0)), d->yearEdit->size());
+ if (!geom.contains(mousePos)) {
+ event->accept();
+ d->_q_yearEditingFinished();
+ setFocus();
+ return true;
}
}
return QWidget::eventFilter(watched, event);
diff --git a/tests/auto/gui/qopengl/tst_qopengl.cpp b/tests/auto/gui/qopengl/tst_qopengl.cpp
index f1360b9efe..ede1e58a53 100644
--- a/tests/auto/gui/qopengl/tst_qopengl.cpp
+++ b/tests/auto/gui/qopengl/tst_qopengl.cpp
@@ -642,6 +642,8 @@ static bool supportsInternalFboFormat(QOpenGLContext *ctx, int glFormat)
return false;
}
}
+#else
+ Q_UNUSED(glFormat);
#endif
return true;
}
diff --git a/tests/auto/gui/text/qtextdocumentfragment/tst_qtextdocumentfragment.cpp b/tests/auto/gui/text/qtextdocumentfragment/tst_qtextdocumentfragment.cpp
index 08f7cf4fb2..fe0b6dae49 100644
--- a/tests/auto/gui/text/qtextdocumentfragment/tst_qtextdocumentfragment.cpp
+++ b/tests/auto/gui/text/qtextdocumentfragment/tst_qtextdocumentfragment.cpp
@@ -196,6 +196,8 @@ private slots:
void css_linkPseudo();
void css_pageBreaks();
void css_cellPaddings();
+ void css_whiteSpace_data();
+ void css_whiteSpace();
void universalSelectors_data();
void universalSelectors();
void screenMedia();
@@ -1771,6 +1773,26 @@ void tst_QTextDocumentFragment::css_cellPaddings()
QCOMPARE(cell.format().toTableCellFormat().bottomPadding(), qreal(15));
}
+void tst_QTextDocumentFragment::css_whiteSpace_data()
+{
+ QTest::addColumn<QString>("htmlText");
+ QTest::addColumn<bool>("nowrap");
+
+ QTest::newRow("default") << QString("<p>Normal Text</p>") << false;
+ QTest::newRow("white-space:nowrap") << QString("<p style=white-space:nowrap>Normal Text</p>") << true;
+ QTest::newRow("white-space:pre") << QString("<p style=white-space:pre>Normal Text</p>") << true;
+}
+
+void tst_QTextDocumentFragment::css_whiteSpace()
+{
+ QFETCH(QString, htmlText);
+ QFETCH(bool, nowrap);
+
+ doc->setHtml(htmlText);
+ QCOMPARE(doc->blockCount(), 1);
+ QCOMPARE(doc->begin().blockFormat().nonBreakableLines(), nowrap);
+}
+
void tst_QTextDocumentFragment::html_blockLevelDiv()
{
const char html[] = "<div align=right><b>Hello World";
diff --git a/tests/auto/widgets/graphicsview/qgraphicsitem/BLACKLIST b/tests/auto/widgets/graphicsview/qgraphicsitem/BLACKLIST
deleted file mode 100644
index 071ccaaff4..0000000000
--- a/tests/auto/widgets/graphicsview/qgraphicsitem/BLACKLIST
+++ /dev/null
@@ -1,3 +0,0 @@
-[cursor]
-# QTBUG-73545
-winrt
diff --git a/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp b/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp
index 37bb28dec9..1d106f94f3 100644
--- a/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp
+++ b/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp
@@ -53,6 +53,8 @@
#include <QStyleOptionSpinBox>
#include <QStyle>
#include <QProxyStyle>
+#include <QScreen>
+
class SpinBox : public QSpinBox
{
@@ -343,6 +345,14 @@ tst_QSpinBox::tst_QSpinBox()
void tst_QSpinBox::init()
{
QLocale::setDefault(QLocale(QLocale::C));
+
+#if QT_CONFIG(cursor)
+ // Ensure mouse cursor was not left by previous tests where widgets
+ // will appear, as it could cause events and interfere with the tests.
+ const QScreen *screen = QGuiApplication::primaryScreen();
+ const QRect availableGeometry = screen->availableGeometry();
+ QCursor::setPos(availableGeometry.topLeft());
+#endif
}
void tst_QSpinBox::setValue_data()