Merge remote-tracking branch 'origin/5.12' into 5.13
Change-Id: I8cad26f17834dbc9f7151edc0f17786f9e32025d
This commit is contained in:
commit
ef2ddcf551
1
INSTALL
1
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
|
||||
|
@ -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/
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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) {
|
||||
|
@ -52,7 +52,8 @@ enum DotNET {
|
||||
NET2012 = 0xb0,
|
||||
NET2013 = 0xc0,
|
||||
NET2015 = 0xd0,
|
||||
NET2017 = 0xe0
|
||||
NET2017 = 0xe0,
|
||||
NET2019
|
||||
};
|
||||
|
||||
DotNET vsVersionFromString(const ProString &versionString);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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];
|
||||
}
|
||||
|
||||
|
@ -59,8 +59,9 @@
|
||||
},
|
||||
"bcm_host": {
|
||||
"export": "",
|
||||
"headers": ["bcm_host.h"],
|
||||
"sources": [
|
||||
"-lbcm_host"
|
||||
{ "type": "makeSpec", "spec": "BCM_HOST" }
|
||||
]
|
||||
},
|
||||
"dxguid": {
|
||||
|
@ -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 ®ion)
|
||||
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 ®ion)
|
||||
// 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 ®ion)
|
||||
*/
|
||||
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 ®ion, 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 ®ion, 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 ®ion, 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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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 ®istryFontKey = 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 ®istryFontKey = 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;
|
||||
|
@ -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.
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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());
|
||||
|
@ -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:
|
||||
|
@ -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)
|
||||
namespace {
|
||||
struct MouseEvent {
|
||||
QEvent::Type type;
|
||||
Qt::MouseButton button;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
static inline Qt::MouseButton extraButton(WPARAM wParam) // for WM_XBUTTON...
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
*mouseButton = buttonMapping.value(changeType, Qt::NoButton);
|
||||
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) {
|
||||
Qt::MouseEventSource source = Qt::MouseEventNotSynthesized;
|
||||
if (isMouseEventSynthesizedFromPenOrTouch()) {
|
||||
if (QWindowsIntegration::instance()->options() & QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch)
|
||||
return false;
|
||||
source = Qt::MouseEventSynthesizedBySystem;
|
||||
}
|
||||
|
||||
if (!isValidWheelReceiver(window))
|
||||
return true;
|
||||
const MouseEvent mouseEvent = eventFromMsg(msg);
|
||||
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
} else if (msg.message == WM_MOUSEMOVE) {
|
||||
|
||||
QWindow *currentWindowUnderPointer = getWindowUnderPointer(window, globalPos);
|
||||
handleCaptureRelease(window, currentWindowUnderPointer, hwnd, QEvent::MouseMove, mouseButtons);
|
||||
handleEnterLeave(window, currentWindowUnderPointer, globalPos);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
handleCaptureRelease(window, currentWindowUnderPointer, hwnd, mouseEvent.type, mouseButtons);
|
||||
handleEnterLeave(window, currentWindowUnderPointer, globalPos);
|
||||
|
||||
if (!discardEvent && mouseEvent.type != QEvent::None) {
|
||||
QWindowSystemInterface::handleMouseEvent(window, localPos, globalPos, mouseButtons,
|
||||
mouseEvent.button, mouseEvent.type, keyModifiers, source);
|
||||
}
|
||||
|
||||
// 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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -136,6 +136,9 @@ public:
|
||||
|
||||
void emulateMouseMove(const QPointF &point, MousePositionTransition transition);
|
||||
|
||||
void setResizePending();
|
||||
bool resizePending() const;
|
||||
|
||||
private:
|
||||
void handleExpose();
|
||||
|
||||
|
@ -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)
|
||||
|
@ -8298,49 +8298,57 @@ void QWidgetPrivate::hide_sys()
|
||||
\endlist
|
||||
*/
|
||||
|
||||
|
||||
void QWidget::setVisible(bool visible)
|
||||
{
|
||||
if (testAttribute(Qt::WA_WState_ExplicitShowHide) && testAttribute(Qt::WA_WState_Hidden) == !visible)
|
||||
return;
|
||||
|
||||
// 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
|
||||
if (testAttribute(Qt::WA_WState_ExplicitShowHide) && !testAttribute(Qt::WA_WState_Hidden))
|
||||
return;
|
||||
|
||||
Q_D(QWidget);
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -642,6 +642,8 @@ static bool supportsInternalFboFormat(QOpenGLContext *ctx, int glFormat)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#else
|
||||
Q_UNUSED(glFormat);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
@ -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";
|
||||
|
@ -1,3 +0,0 @@
|
||||
[cursor]
|
||||
# QTBUG-73545
|
||||
winrt
|
@ -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()
|
||||
|
Loading…
x
Reference in New Issue
Block a user