Merge remote-tracking branch 'origin/5.12' into 5.13

Change-Id: I26da00aa71b0f0b91c9bfb4a9e8550345ee62875
This commit is contained in:
Qt Forward Merge Bot 2019-04-24 01:00:12 +02:00
commit cb10ec56f7
30 changed files with 482 additions and 168 deletions

View File

@ -1111,7 +1111,7 @@ foreach my $lib (@modules_to_sync) {
elsif (!$shadow) {
$pri_install_pfiles.= "$pri_install_iheader ";;
}
$pri_injections .= fixPaths($iheader, $out_basedir)
$pri_injections .= fixPaths($iheader, $build_basedir)
.":".($no_stamp ? "^" : "").fixPaths($oheader, "$out_basedir/include/$lib")
.$injection." " if ($shadow);
}

82
dist/changes-5.12.3 vendored Normal file
View File

@ -0,0 +1,82 @@
Qt 5.12.3 is a bug-fix release. It maintains both forward and backward
compatibility (source and binary) with Qt 5.12.0 through 5.12.2.
For more details, refer to the online documentation included in this
distribution. The documentation is also available online:
https://doc.qt.io/qt-5/index.html
The Qt version 5.12 series is binary compatible with the 5.11.x series.
Applications compiled for 5.11 will continue to run with 5.12.
Some of the changes listed in this file include issue tracking numbers
corresponding to tasks in the Qt Bug Tracker:
https://bugreports.qt.io/
Each of these identifiers can be entered in the bug tracker to obtain more
information about a particular change.
****************************************************************************
* Third-Party Code *
****************************************************************************
- Changed classification of the wintab license from Public Domain to
Custom.
****************************************************************************
* QtCore *
****************************************************************************
- Event system:
* [QTBUG-72438] Fixed a possible race condition on Windows that would
cause an interrupted event loop to be stuck until more events were
posted.
- Logging system:
* [QTBUG-74359] Fixed the compilation of qCDebug("", ...) when debug
output was disabled.
- QCollator:
* [QTBUG-74209] Fixed a bug that caused QCompare to incorrect return a
sorting order on Windows if the Win32 API failed.
- QDateTime / QTimeZone:
* [QTBUG-74614] Fixed handling of timezones that contain no DST
transitions.
- QProcess:
* [QTBUG-73778] Fixed a crash when calling closeWriteChannel() on Windows.
****************************************************************************
* QtSql *
****************************************************************************
- When cross-compiling pg_config, mysql_config are not looked up in PATH
anymore. Pass -psql_config path/to/pg_config or -mysql_config
path/to/mysql_config to explicitly enable PSQL or MySQL in this setup.
****************************************************************************
* Platform Specific Changes *
****************************************************************************
- Android:
* Text fields with ImhNoPredictiveText set are no longer working around
keyboards that disregard this setting. To enforce the workaround, the
environment variable
QT_ANDROID_ENABLE_WORKAROUND_TO_DISABLE_PREDICTIVE_TEXT should be set.
* [QTBUG-74029] Added entries in the AndroidManifest.xml for specific
portrait and landscape splash screens. If one is present for the current
orientation, it will be preferred over the generic one.
- Linux:
* [QTBUG-74526] Changed the way we use the statx() system call to use a
fallback mechanism provided by the GNU C library. This should allow Qt
applications that are compiled with glibc >= 2.28 to run even on kernels
older than 4.11.
- Windows:
* [QTBUG-74062] Fixed QToolTip pop-ups and QComboBox animation pop-ups
being off by a few pixels on Windows 10.

View File

@ -519,6 +519,17 @@ defineTest(qtConfSetupLibraries) {
}
}
defineReplace(qtGccSysrootifiedPath) {
return($$replace(1, ^=, $$[QT_SYSROOT]))
}
defineReplace(qtGccSysrootifiedPaths) {
sysrootified =
for (path, 1): \
sysrootified += $$qtGccSysrootifiedPath($$path)
return($$sysrootified)
}
# libs-var, libs, in-paths, out-paths-var
defineTest(qtConfResolveLibs) {
ret = true
@ -535,6 +546,7 @@ defineTest(qtConfResolveLibs) {
out += $$l
} else: contains(l, "^-L.*") {
lp = $$replace(l, "^-L", )
gcc: lp = $$qtGccSysrootifiedPath($$lp)
!exists($$lp/.) {
qtLog("Library path $$val_escape(lp) is invalid.")
ret = false
@ -608,6 +620,7 @@ defineTest(qtConfResolveAllLibs) {
# libs-var, in-paths, libs
defineTest(qtConfResolvePathLibs) {
ret = true
gcc: 2 = $$qtGccSysrootifiedPaths($$2)
for (libdir, 2) {
!exists($$libdir/.) {
qtLog("Library path $$val_escape(libdir) is invalid.")
@ -658,6 +671,7 @@ defineReplace(qtConfGetTestIncludes) {
# includes-var, in-paths, test-object-var
defineTest(qtConfResolvePathIncs) {
ret = true
gcc: 2 = $$qtGccSysrootifiedPaths($$2)
for (incdir, 2) {
!exists($$incdir/.) {
qtLog("Include path $$val_escape(incdir) is invalid.")

View File

@ -23,7 +23,7 @@ load(qt_build_paths)
QMAKE_SYNCQT += -module $$mod
QMAKE_SYNCQT += \
-version $$VERSION -outdir $$system_quote($$MODULE_BASE_OUTDIR) \
-builddir $$system_quote($$shadowed($$MODULE_BASE_INDIR)) $$MODULE_SYNCQT_DIR
-builddir $$system_quote($$REAL_MODULE_BASE_OUTDIR) $$MODULE_SYNCQT_DIR
!silent: message($$QMAKE_SYNCQT)
system($$QMAKE_SYNCQT)|error("Failed to run: $$QMAKE_SYNCQT")

View File

@ -1615,6 +1615,14 @@
The value of this variable is typically handled by qmake or \l{#QMAKESPEC}{qmake.conf}
and rarely needs to be modified.
\target QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO
\section1 QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO
Specifies the C compiler flags for release builds where
\c{force_debug_info} is set in \c{CONFIG}.
The value of this variable is typically handled by
qmake or \l{#QMAKESPEC}{qmake.conf} and rarely needs to be modified.
\target QMAKE_CFLAGS_SHLIB
\section1 QMAKE_CFLAGS_SHLIB
@ -1683,6 +1691,14 @@
The value of this variable is typically handled by
qmake or \l{#QMAKESPEC}{qmake.conf} and rarely needs to be modified.
\target QMAKE_CXXFLAGS_RELEASE_WITH_DEBUGINFO
\section1 QMAKE_CXXFLAGS_RELEASE_WITH_DEBUGINFO
Specifies the C++ compiler flags for release builds where
\c{force_debug_info} is set in \c{CONFIG}.
The value of this variable is typically handled by
qmake or \l{#QMAKESPEC}{qmake.conf} and rarely needs to be modified.
\target QMAKE_CXXFLAGS_SHLIB
\section1 QMAKE_CXXFLAGS_SHLIB
@ -2063,6 +2079,12 @@
The value of this variable is typically handled by
qmake or \l{#QMAKESPEC}{qmake.conf} and rarely needs to be modified.
\section1 QMAKE_LFLAGS_RELEASE_WITH_DEBUGINFO
Specifies the linker flags for release builds where \c{force_debug_info} is
set in \c{CONFIG}. The value of this variable is typically handled by
qmake or \l{#QMAKESPEC}{qmake.conf} and rarely needs to be modified.
\section1 QMAKE_LFLAGS_APP
Specifies the linker flags for building applications.

View File

@ -142,6 +142,7 @@ const char _InterfaceIdentifierFileName[] = "InterfaceIdentifierFileName";
const char _IntermediateDirectory[] = "IntermediateDirectory";
const char _KeyContainer[] = "KeyContainer";
const char _KeyFile[] = "KeyFile";
const char _LanguageStandard[] = "LanguageStandard";
const char _LargeAddressAware[] = "LargeAddressAware";
const char _LinkDLL[] = "LinkDLL";
const char _LinkErrorReporting[] = "LinkErrorReporting";
@ -1477,6 +1478,7 @@ void VCXProjectWriter::write(XmlOutput &xml, const VCCLCompilerTool &tool)
<< attrTagT(_IntrinsicFunctions, tool.EnableIntrinsicFunctions)
<< attrTagT(_MinimalRebuild, tool.MinimalRebuild)
<< attrTagT(_MultiProcessorCompilation, tool.MultiProcessorCompilation)
<< attrTagS(_LanguageStandard, tool.LanguageStandard)
<< attrTagS(_ObjectFileName, tool.ObjectFile)
<< attrTagT(_OmitDefaultLibName, tool.OmitDefaultLibName)
<< attrTagT(_OmitFramePointers, tool.OmitFramePointers)

View File

@ -1146,6 +1146,14 @@ bool VCCLCompilerTool::parseOption(const char* option)
ShowIncludes = _True;
break;
}
if (strlen(option) > 8 && second == 't' && third == 'd') {
const QString version = option + 8;
static const QStringList knownVersions = { "14", "17", "latest" };
if (knownVersions.contains(version)) {
LanguageStandard = "stdcpp" + version;
break;
}
}
found = false; break;
case 'u':
if (!second)

View File

@ -526,6 +526,7 @@ public:
triState ImproveFloatingPointConsistency;
inlineExpansionOption InlineFunctionExpansion;
triState KeepComments;
QString LanguageStandard;
triState MinimalRebuild;
QString ObjectFile;
triState OmitDefaultLibName;

View File

@ -364,6 +364,23 @@ Display *Display::GetDisplayFromDevice(Device *device, const AttributeMap &attri
return display;
}
//static
void Display::CleanupDisplays()
{
// ~Display takes care of removing the entry from the according map
{
ANGLEPlatformDisplayMap *displays = GetANGLEPlatformDisplayMap();
while (!displays->empty())
delete displays->begin()->second;
}
{
DevicePlatformDisplayMap *displays = GetDevicePlatformDisplayMap();
while (!displays->empty())
delete displays->begin()->second;
}
}
Display::Display(EGLenum platform, EGLNativeDisplayType displayId, Device *eglDevice)
: mImplementation(nullptr),
mDisplayId(displayId),

View File

@ -65,6 +65,7 @@ class Display final : angle::NonCopyable
static Display *GetDisplayFromDevice(Device *device, const AttributeMap &attribMap);
static Display *GetDisplayFromNativeDisplay(EGLNativeDisplayType nativeDisplay,
const AttributeMap &attribMap);
static void CleanupDisplays();
static const ClientExtensions &GetClientExtensions();
static const std::string &GetClientExtensionString();

View File

@ -13,6 +13,7 @@
#include "common/tls.h"
#include "libANGLE/Thread.h"
#include "libANGLE/Display.h"
namespace gl
{
@ -140,6 +141,7 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE, DWORD reason, LPVOID)
return static_cast<BOOL>(egl::DeallocateCurrentThread());
case DLL_PROCESS_DETACH:
egl::Display::CleanupDisplays();
return static_cast<BOOL>(egl::TerminateProcess());
}

View File

@ -0,0 +1,78 @@
From d8ca4f6d0d8fffd8319f340685e03751049678ae Mon Sep 17 00:00:00 2001
From: Oliver Wolff <oliver.wolff@qt.io>
Date: Tue, 16 Apr 2019 10:19:27 +0200
Subject: [PATCH] ANGLE: clean up displays on dll unload
If the displays are not cleaned up on dll unloading, profilers might
report memory leaks.
Change-Id: I04cbc3c2448bfb450f7d840e216827f86856e963
---
src/3rdparty/angle/src/libANGLE/Display.cpp | 17 +++++++++++++++++
src/3rdparty/angle/src/libANGLE/Display.h | 1 +
.../angle/src/libGLESv2/global_state.cpp | 2 ++
3 files changed, 20 insertions(+)
diff --git a/src/3rdparty/angle/src/libANGLE/Display.cpp b/src/3rdparty/angle/src/libANGLE/Display.cpp
index 735b472787..0bb0bb05b1 100644
--- a/src/3rdparty/angle/src/libANGLE/Display.cpp
+++ b/src/3rdparty/angle/src/libANGLE/Display.cpp
@@ -364,6 +364,23 @@ Display *Display::GetDisplayFromDevice(Device *device, const AttributeMap &attri
return display;
}
+//static
+void Display::CleanupDisplays()
+{
+ // ~Display takes care of removing the entry from the according map
+ {
+ ANGLEPlatformDisplayMap *displays = GetANGLEPlatformDisplayMap();
+ while (!displays->empty())
+ delete displays->begin()->second;
+ }
+
+ {
+ DevicePlatformDisplayMap *displays = GetDevicePlatformDisplayMap();
+ while (!displays->empty())
+ delete displays->begin()->second;
+ }
+}
+
Display::Display(EGLenum platform, EGLNativeDisplayType displayId, Device *eglDevice)
: mImplementation(nullptr),
mDisplayId(displayId),
diff --git a/src/3rdparty/angle/src/libANGLE/Display.h b/src/3rdparty/angle/src/libANGLE/Display.h
index aa1d1c3b37..2a1c386d75 100644
--- a/src/3rdparty/angle/src/libANGLE/Display.h
+++ b/src/3rdparty/angle/src/libANGLE/Display.h
@@ -65,6 +65,7 @@ class Display final : angle::NonCopyable
static Display *GetDisplayFromDevice(Device *device, const AttributeMap &attribMap);
static Display *GetDisplayFromNativeDisplay(EGLNativeDisplayType nativeDisplay,
const AttributeMap &attribMap);
+ static void CleanupDisplays();
static const ClientExtensions &GetClientExtensions();
static const std::string &GetClientExtensionString();
diff --git a/src/3rdparty/angle/src/libGLESv2/global_state.cpp b/src/3rdparty/angle/src/libGLESv2/global_state.cpp
index c5f3dfe4e1..26045bf5b2 100644
--- a/src/3rdparty/angle/src/libGLESv2/global_state.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/global_state.cpp
@@ -13,6 +13,7 @@
#include "common/tls.h"
#include "libANGLE/Thread.h"
+#include "libANGLE/Display.h"
namespace gl
{
@@ -140,6 +141,7 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE, DWORD reason, LPVOID)
return static_cast<BOOL>(egl::DeallocateCurrentThread());
case DLL_PROCESS_DETACH:
+ egl::Display::CleanupDisplays();
return static_cast<BOOL>(egl::TerminateProcess());
}
--
2.20.1.windows.1

View File

@ -930,7 +930,7 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel
*/
/*!
\fn quint32 QRandomGenerator::bounded(int highest)
\fn int QRandomGenerator::bounded(int highest)
\overload
Generates one random 32-bit quantity in the range between 0 (inclusive) and
@ -957,7 +957,6 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel
\snippet code/src_corelib_global_qrandom.cpp 14
Note that this function cannot be used to obtain values in the full 32-bit
range of quint32. Instead, use generate().
@ -965,7 +964,7 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel
*/
/*!
\fn quint32 QRandomGenerator::bounded(int lowest, int highest)
\fn int QRandomGenerator::bounded(int lowest, int highest)
\overload
Generates one random 32-bit quantity in the range between \a lowest

View File

@ -366,40 +366,35 @@ void qt_mac_scale_region(QRegion *region, qreal scaleFactor)
// ---------------------- QMacCGContext ----------------------
QMacCGContext::QMacCGContext(QPaintDevice *paintDevice) : context(0)
QMacCGContext::QMacCGContext(QPaintDevice *paintDevice)
{
// In Qt 5, QWidget and QPixmap (and QImage) paint devices are all QImages under the hood.
QImage *image = 0;
if (paintDevice->devType() == QInternal::Image) {
image = static_cast<QImage *>(paintDevice);
} else if (paintDevice->devType() == QInternal::Pixmap) {
const QPixmap *pm = static_cast<const QPixmap*>(paintDevice);
QPlatformPixmap *data = const_cast<QPixmap *>(pm)->data_ptr().data();
if (data && data->classId() == QPlatformPixmap::RasterClass) {
image = data->buffer();
} else {
qDebug("QMacCGContext: Unsupported pixmap class");
}
} else if (paintDevice->devType() == QInternal::Widget) {
// TODO test: image = static_cast<QImage *>(static_cast<const QWidget *>(paintDevice)->backingStore()->paintDevice());
qDebug("QMacCGContext: not implemented: Widget class");
}
if (!image)
return; // Context type not supported.
QCFType<CGColorSpaceRef> colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB);
context = CGBitmapContextCreate(image->bits(), image->width(), image->height(), 8,
image->bytesPerLine(), colorSpace, qt_mac_bitmapInfoForImage(*image));
CGContextTranslateCTM(context, 0, image->height());
const qreal devicePixelRatio = paintDevice->devicePixelRatioF();
CGContextScaleCTM(context, devicePixelRatio, devicePixelRatio);
CGContextScaleCTM(context, 1, -1);
initialize(paintDevice);
}
QMacCGContext::QMacCGContext(QPainter *painter) : context(0)
void QMacCGContext::initialize(QPaintDevice *paintDevice)
{
// Find the underlying QImage of the paint device
switch (int deviceType = paintDevice->devType()) {
case QInternal::Pixmap: {
auto *platformPixmap = static_cast<QPixmap*>(paintDevice)->handle();
if (platformPixmap && platformPixmap->classId() == QPlatformPixmap::RasterClass)
initialize(platformPixmap->buffer());
else
qWarning() << "QMacCGContext: Unsupported pixmap class" << platformPixmap->classId();
break;
}
case QInternal::Image:
initialize(static_cast<const QImage *>(paintDevice));
break;
case QInternal::Widget:
qWarning() << "QMacCGContext: not implemented: Widget class";
break;
default:
qWarning() << "QMacCGContext:: Unsupported paint device type" << deviceType;
}
}
QMacCGContext::QMacCGContext(QPainter *painter)
{
QPaintEngine *paintEngine = painter->paintEngine();
@ -414,51 +409,68 @@ QMacCGContext::QMacCGContext(QPainter *painter) : context(0)
return;
}
int devType = painter->device()->devType();
if (paintEngine->type() == QPaintEngine::Raster
&& (devType == QInternal::Widget ||
devType == QInternal::Pixmap ||
devType == QInternal::Image)) {
const QImage *image = static_cast<const QImage *>(paintEngine->paintDevice());
QCFType<CGColorSpaceRef> colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB);
context = CGBitmapContextCreate((void *)image->bits(), image->width(), image->height(), 8,
image->bytesPerLine(), colorSpace, qt_mac_bitmapInfoForImage(*image));
// Invert y axis
CGContextTranslateCTM(context, 0, image->height());
CGContextScaleCTM(context, 1, -1);
const qreal devicePixelRatio = image->devicePixelRatio();
if (devType == QInternal::Widget) {
// Set the clip rect which is an intersection of the system clip
// and the painter clip. To make matters more interesting these
// are in device pixels and device-independent pixels, respectively.
QRegion clip = painter->paintEngine()->systemClip(); // get system clip in device pixels
QTransform native = painter->deviceTransform(); // get device transform. dx/dy is in device pixels
if (painter->hasClipping()) {
QRegion r = painter->clipRegion(); // get painter clip, which is in device-independent pixels
qt_mac_scale_region(&r, devicePixelRatio); // scale painter clip to device pixels
r.translate(native.dx(), native.dy());
if (clip.isEmpty())
clip = r;
else
clip &= r;
}
qt_mac_clip_cg(context, clip, 0); // clip in device pixels
// Scale the context so that painting happens in device-independent pixels
CGContextScaleCTM(context, devicePixelRatio, devicePixelRatio);
CGContextTranslateCTM(context, native.dx() / devicePixelRatio, native.dy() / devicePixelRatio);
} else {
// Scale to paint in device-independent pixels
CGContextScaleCTM(context, devicePixelRatio, devicePixelRatio);
}
} else {
qDebug() << "QMacCGContext:: Unsupported painter devtype type" << devType;
if (paintEngine->type() != QPaintEngine::Raster) {
qWarning() << "QMacCGContext:: Unsupported paint engine type" << paintEngine->type();
return;
}
// The raster paint engine always operates on a QImage
Q_ASSERT(paintEngine->paintDevice()->devType() == QInternal::Image);
// On behalf of one of these supported painter devices
switch (int painterDeviceType = painter->device()->devType()) {
case QInternal::Pixmap:
case QInternal::Image:
case QInternal::Widget:
break;
default:
qWarning() << "QMacCGContext:: Unsupported paint device type" << painterDeviceType;
return;
}
// Applying the clip is so entangled with the rest of the context setup
// that for simplicity we just pass in the painter.
initialize(static_cast<const QImage *>(paintEngine->paintDevice()), painter);
}
void QMacCGContext::initialize(const QImage *image, QPainter *painter)
{
QCFType<CGColorSpaceRef> colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB);
context = CGBitmapContextCreate((void *)image->bits(), image->width(), image->height(), 8,
image->bytesPerLine(), colorSpace, qt_mac_bitmapInfoForImage(*image));
// Invert y axis
CGContextTranslateCTM(context, 0, image->height());
CGContextScaleCTM(context, 1, -1);
const qreal devicePixelRatio = image->devicePixelRatio();
if (painter && painter->device()->devType() == QInternal::Widget) {
// Set the clip rect which is an intersection of the system clip and the painter clip
QRegion clip = painter->paintEngine()->systemClip();
QTransform deviceTransform = painter->deviceTransform();
if (painter->hasClipping()) {
// To make matters more interesting the painter clip is in device-independent pixels,
// so we need to scale it to match the device-pixels of the system clip.
QRegion painterClip = painter->clipRegion();
qt_mac_scale_region(&painterClip, devicePixelRatio);
painterClip.translate(deviceTransform.dx(), deviceTransform.dy());
if (clip.isEmpty())
clip = painterClip;
else
clip &= painterClip;
}
qt_mac_clip_cg(context, clip, 0);
CGContextTranslateCTM(context, deviceTransform.dx(), deviceTransform.dy());
}
// Scale the context so that painting happens in device-independent pixels
CGContextScaleCTM(context, devicePixelRatio, devicePixelRatio);
}
QT_END_NAMESPACE

View File

@ -51,6 +51,8 @@
// We mean it.
//
#include <QtCore/private/qcore_mac_p.h>
#include <QtGui/private/qtguiglobal_p.h>
#include <QtGui/qregion.h>
#include <QtGui/qpalette.h>
@ -89,38 +91,16 @@ Q_GUI_EXPORT QBrush qt_mac_toQBrush(CGColorRef color);
class Q_GUI_EXPORT QMacCGContext
{
public:
inline QMacCGContext() { context = 0; }
QMacCGContext() = default;
QMacCGContext(QPaintDevice *pdev);
QMacCGContext(QPainter *p);
inline QMacCGContext(CGContextRef cg, bool takeOwnership = false) {
context = cg;
if (!takeOwnership)
CGContextRetain(context);
}
inline QMacCGContext(const QMacCGContext &copy) : context(0) { *this = copy; }
inline ~QMacCGContext() {
if (context)
CGContextRelease(context);
}
inline bool isNull() const { return context; }
inline operator CGContextRef() { return context; }
inline QMacCGContext &operator=(const QMacCGContext &copy) {
if (context)
CGContextRelease(context);
context = copy.context;
CGContextRetain(context);
return *this;
}
inline QMacCGContext &operator=(CGContextRef cg) {
if (context)
CGContextRelease(context);
context = cg;
CGContextRetain(context); //we do not take ownership
return *this;
}
operator CGContextRef() { return context; }
private:
CGContextRef context;
void initialize(QPaintDevice *paintDevice);
void initialize(const QImage *, QPainter *painter = nullptr);
QCFType<CGContextRef> context;
};
QT_END_NAMESPACE

View File

@ -385,8 +385,8 @@ QHostAddress QNetmask::address(QAbstractSocket::NetworkLayerProtocol protocol) c
\value LocalHost The IPv4 localhost address. Equivalent to QHostAddress("127.0.0.1").
\value LocalHostIPv6 The IPv6 localhost address. Equivalent to QHostAddress("::1").
\value Broadcast The IPv4 broadcast address. Equivalent to QHostAddress("255.255.255.255").
\value AnyIPv4 The IPv4 any-address. Equivalent to QHostAddress("0.0.0.0"). A socket bound with this address will listen only on IPv4 interaces.
\value AnyIPv6 The IPv6 any-address. Equivalent to QHostAddress("::"). A socket bound with this address will listen only on IPv6 interaces.
\value AnyIPv4 The IPv4 any-address. Equivalent to QHostAddress("0.0.0.0"). A socket bound with this address will listen only on IPv4 interfaces.
\value AnyIPv6 The IPv6 any-address. Equivalent to QHostAddress("::"). A socket bound with this address will listen only on IPv6 interfaces.
\value Any The dual stack any-address. A socket bound with this address will listen on both IPv4 and IPv6 interfaces.
*/

View File

@ -188,14 +188,15 @@ static inline QRect toBottomLeftRect(const QRect &topLeftRect, int windowHeight)
topLeftRect.width(), topLeftRect.height());
}
static void clippedBlit(const QPlatformTextureList *textures, int idx, const QRect &targetWindowRect,
static void clippedBlit(const QPlatformTextureList *textures, int idx, const QRect &sourceWindowRect,
const QRect &targetWindowRect,
QOpenGLTextureBlitter *blitter, QMatrix4x4 *rotationMatrix)
{
const QRect clipRect = textures->clipRect(idx);
if (clipRect.isEmpty())
return;
const QRect rectInWindow = textures->geometry(idx);
const QRect rectInWindow = textures->geometry(idx).translated(sourceWindowRect.topLeft());
const QRect clippedRectInWindow = rectInWindow & clipRect.translated(rectInWindow.topLeft());
const QRect srcRect = toBottomLeftRect(clipRect, rectInWindow.height());
@ -218,7 +219,7 @@ void QOpenGLCompositor::render(QOpenGLCompositorWindow *window)
const QRect targetWindowRect(QPoint(0, 0), m_targetWindow->geometry().size());
float currentOpacity = 1.0f;
BlendStateBinder blend;
const QRect sourceWindowRect = window->sourceWindow()->geometry();
for (int i = 0; i < textures->count(); ++i) {
uint textureId = textures->textureId(i);
const float opacity = window->sourceWindow()->opacity();
@ -243,16 +244,16 @@ void QOpenGLCompositor::render(QOpenGLCompositorWindow *window)
target = m_rotationMatrix * target;
m_blitter.blit(textureId, target, QOpenGLTextureBlitter::OriginTopLeft);
} else if (!textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop)) {
// Texture from an FBO belonging to a QOpenGLWidget
// Texture from an FBO belonging to a QOpenGLWidget or QQuickWidget
blend.set(false);
clippedBlit(textures, i, targetWindowRect, &m_blitter, m_rotation ? &m_rotationMatrix : nullptr);
clippedBlit(textures, i, sourceWindowRect, targetWindowRect, &m_blitter, m_rotation ? &m_rotationMatrix : nullptr);
}
}
for (int i = 0; i < textures->count(); ++i) {
if (textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop)) {
blend.set(true);
clippedBlit(textures, i, targetWindowRect, &m_blitter, m_rotation ? &m_rotationMatrix : nullptr);
clippedBlit(textures, i, sourceWindowRect, targetWindowRect, &m_blitter, m_rotation ? &m_rotationMatrix : nullptr);
}
}

View File

@ -93,6 +93,7 @@ private:
QRegion dirtyRegion; // In unscaled coordinates
QImage *asImage();
qreal devicePixelRatio() const { return m_devicePixelRatio; }
private:
qreal m_devicePixelRatio;

View File

@ -460,12 +460,29 @@ void QCALayerBackingStore::flush(QWindow *flushedWindow, const QRegion &region,
NSView *backingStoreView = static_cast<QCocoaWindow *>(window()->handle())->view();
NSView *flushedView = static_cast<QCocoaWindow *>(flushedWindow->handle())->view();
// If the backingstore is just flushed, without being painted to first, then we may
// end in a situation where the backingstore is flushed to a layer with a different
// scale factor than the one it was created for in beginPaint. This is the client's
// fault in not picking up the change in scale factor of the window and re-painting
// the backingstore accordingly. To smoothing things out, we warn about this situation,
// and change the layer's contentsScale to match the scale of the back buffer, so that
// we at least cover the whole layer. This is necessary since we set the view's
// contents placement policy to NSViewLayerContentsPlacementTopLeft, which means
// AppKit will not do any scaling on our behalf.
if (m_buffers.back()->devicePixelRatio() != flushedView.layer.contentsScale) {
qCWarning(lcQpaBackingStore) << "Back buffer dpr of" << m_buffers.back()->devicePixelRatio()
<< "doesn't match" << flushedView.layer << "contents scale of" << flushedView.layer.contentsScale
<< "- updating layer to match.";
flushedView.layer.contentsScale = m_buffers.back()->devicePixelRatio();
}
id backBufferSurface = (__bridge id)m_buffers.back()->surface();
if (flushedView.layer.contents == backBufferSurface) {
// We've managed to paint to the back buffer again before Core Animation had time
// to flush the transaction and persist the layer changes to the window server.
// The layer already knows about the back buffer, and we don't need to re-apply
// it to pick up the surface changes, so bail out early.
// to flush the transaction and persist the layer changes to the window server, or
// we've been asked to flush without painting anything. The layer already knows about
// the back buffer, and we don't need to re-apply it to pick up any possible surface
// changes, so bail out early.
qCInfo(lcQpaBackingStore).nospace() << "Skipping flush of " << flushedView
<< ", layer already reflects back buffer";
return;

View File

@ -199,6 +199,10 @@ QPlatformWindow *QEglFSIntegration::createPlatformWindow(QWindow *window) const
QEglFSWindow *w = qt_egl_device_integration()->createWindow(window);
w->create();
const auto showWithoutActivating = window->property("_q_showWithoutActivating");
if (showWithoutActivating.isValid() && showWithoutActivating.toBool())
return w;
// Activate only the window for the primary screen to make input work
if (window->type() != Qt::ToolTip && window->screen() == QGuiApplication::primaryScreen())
w->requestActivateWindow();

View File

@ -167,6 +167,9 @@ void QEglFSWindow::create()
void QEglFSWindow::destroy()
{
if (!m_flags.testFlag(Created))
return; // already destroyed
#ifndef QT_NO_OPENGL
QOpenGLCompositor::instance()->removeWindow(this);
#endif

View File

@ -55,6 +55,9 @@ public:
: QEglFSWindow(w),
m_integration(integration)
{ }
~QEglFSKmsGbmWindow() { destroy(); }
void resetSurface() override;
void invalidateSurface() override;

View File

@ -116,6 +116,8 @@ public:
, m_egl_stream(EGL_NO_STREAM_KHR)
{ }
~QEglFSKmsEglDeviceWindow() { destroy(); }
void invalidateSurface() override;
void resetSurface() override;

View File

@ -205,6 +205,9 @@ public:
: QEglFSWindow(w)
, m_integration(integration)
{}
~QEglFSKmsVsp2Window() { destroy(); }
void resetSurface() override;
void invalidateSurface() override;
const QEglFSKmsVsp2Integration *m_integration;

View File

@ -41,6 +41,7 @@
#include <QtCore/qurl.h>
#include <QtCore/qmimedata.h>
#include "qwindowsmime.h"
QT_BEGIN_NAMESPACE
@ -48,8 +49,9 @@ QT_BEGIN_NAMESPACE
\class QWindowsDropDataObject
\brief QWindowsOleDataObject subclass specialized for handling Drag&Drop.
Only allows "text/uri-list" data to be exported as CF_HDROP, to allow dropped
files to be attached to Office applications (instead of adding an URL link).
Prevents "text/uri-list" data for local files from being exported as text
or URLs, to allow dropped files to be attached to Office applications
(instead of creating local hyperlinks).
\internal
\ingroup qt-lighthouse-win
@ -80,14 +82,22 @@ QWindowsDropDataObject::QueryGetData(LPFORMATETC pformatetc)
return QWindowsOleDataObject::QueryGetData(pformatetc);
}
// If the data is text/uri-list for local files, tell we can only export it as CF_HDROP.
// If the data is "text/uri-list" only, and all URIs are for local files,
// we prevent it from being exported as text or URLs, to make target applications
// like MS Office attach or open the files instead of creating local hyperlinks.
bool QWindowsDropDataObject::shouldIgnore(LPFORMATETC pformatetc) const
{
QMimeData *dropData = mimeData();
if (dropData && dropData->hasFormat(QStringLiteral("text/uri-list")) && (pformatetc->cfFormat != CF_HDROP)) {
QList<QUrl> urls = dropData->urls();
return std::any_of(urls.cbegin(), urls.cend(), [] (const QUrl &u) { return u.isLocalFile(); });
if (dropData && dropData->formats().size() == 1 && dropData->hasUrls()) {
QString formatName = QWindowsMimeConverter::clipboardFormatName(pformatetc->cfFormat);
if (pformatetc->cfFormat == CF_UNICODETEXT
|| pformatetc->cfFormat == CF_TEXT
|| formatName == QStringLiteral("UniformResourceLocator")
|| formatName == QStringLiteral("UniformResourceLocatorW")) {
QList<QUrl> urls = dropData->urls();
return std::all_of(urls.cbegin(), urls.cend(), [] (const QUrl &u) { return u.isLocalFile(); });
}
}
return false;

View File

@ -879,21 +879,16 @@ bool QWindowsKeyMapper::translateMultimediaKeyEventInternal(QWindow *window, con
#if defined(WM_APPCOMMAND)
const int cmd = GET_APPCOMMAND_LPARAM(msg.lParam);
// QTBUG-57198, do not send mouse-synthesized commands as key events in addition
bool skipPressRelease = false;
switch (GET_DEVICE_LPARAM(msg.lParam)) {
case FAPPCOMMAND_MOUSE:
return false;
case FAPPCOMMAND_KEY:
// QTBUG-62838, swallow WM_KEYDOWN, WM_KEYUP for commands that are
// reflected in VK(s) like VK_MEDIA_NEXT_TRACK. Don't do that for
// APPCOMMAND_BROWSER_HOME as that one does not trigger two events
if (cmd != APPCOMMAND_BROWSER_HOME) {
MSG peekedMsg;
if (PeekMessage(&peekedMsg, msg.hwnd, 0, 0, PM_NOREMOVE)
&& peekedMsg.message == WM_KEYDOWN) {
PeekMessage(&peekedMsg, msg.hwnd, 0, 0, PM_REMOVE);
PeekMessage(&peekedMsg, msg.hwnd, 0, 0, PM_REMOVE);
}
}
// QTBUG-62838, use WM_KEYDOWN/WM_KEYUP for commands that are reflected
// in VK(s) like VK_MEDIA_NEXT_TRACK, to get correct codes and autorepeat.
// Don't do that for APPCOMMAND_BROWSER_HOME as that one does not trigger two events.
if (cmd != APPCOMMAND_BROWSER_HOME)
skipPressRelease = true;
break;
}
@ -908,7 +903,8 @@ bool QWindowsKeyMapper::translateMultimediaKeyEventInternal(QWindow *window, con
return false;
const int qtKey = int(CmdTbl[cmd]);
sendExtendedPressRelease(receiver, qtKey, Qt::KeyboardModifier(state), 0, 0, 0);
if (!skipPressRelease)
sendExtendedPressRelease(receiver, qtKey, Qt::KeyboardModifier(state), 0, 0, 0);
// QTBUG-43343: Make sure to return false if Qt does not handle the key, otherwise,
// the keys are not passed to the active media player.
# if QT_CONFIG(shortcut)

View File

@ -250,6 +250,23 @@ static Qt::MouseButtons mouseButtonsFromKeyState(WPARAM keyState)
return result;
}
static Qt::MouseButtons queryMouseButtons()
{
Qt::MouseButtons result = Qt::NoButton;
const bool mouseSwapped = GetSystemMetrics(SM_SWAPBUTTON);
if (GetAsyncKeyState(VK_LBUTTON) < 0)
result |= mouseSwapped ? Qt::RightButton: Qt::LeftButton;
if (GetAsyncKeyState(VK_RBUTTON) < 0)
result |= mouseSwapped ? Qt::LeftButton : Qt::RightButton;
if (GetAsyncKeyState(VK_MBUTTON) < 0)
result |= Qt::MidButton;
if (GetAsyncKeyState(VK_XBUTTON1) < 0)
result |= Qt::XButton1;
if (GetAsyncKeyState(VK_XBUTTON2) < 0)
result |= Qt::XButton2;
return result;
}
static QWindow *getWindowUnderPointer(QWindow *window, QPoint globalPos)
{
QWindow *currentWindowUnderPointer = QWindowsScreen::windowAt(globalPos, CWP_SKIPINVISIBLE | CWP_SKIPTRANSPARENT);
@ -531,7 +548,7 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin
if (!QWindowsContext::user32dll.getPointerDeviceRects(penInfo->pointerInfo.sourceDevice, &pRect, &dRect))
return false;
const quint32 pointerId = penInfo->pointerInfo.pointerId;
const qint64 sourceDevice = (qint64)penInfo->pointerInfo.sourceDevice;
const QPoint globalPos = QPoint(penInfo->pointerInfo.ptPixelLocation.x, penInfo->pointerInfo.ptPixelLocation.y);
const QPoint localPos = QWindowsGeometryHint::mapFromGlobal(hwnd, globalPos);
const QPointF hiResGlobalPos = QPointF(dRect.left + qreal(penInfo->pointerInfo.ptHimetricLocation.x - pRect.left)
@ -547,7 +564,7 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin
if (QWindowsContext::verbose > 1)
qCDebug(lcQpaEvents).noquote().nospace() << showbase
<< __FUNCTION__ << " pointerId=" << pointerId
<< __FUNCTION__ << " sourceDevice=" << sourceDevice
<< " globalPos=" << globalPos << " localPos=" << localPos << " hiResGlobalPos=" << hiResGlobalPos
<< " message=" << hex << msg.message
<< " flags=" << hex << penInfo->pointerInfo.pointerFlags;
@ -570,7 +587,7 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin
switch (msg.message) {
case WM_POINTERENTER: {
QWindowSystemInterface::handleTabletEnterProximityEvent(device, type, pointerId);
QWindowSystemInterface::handleTabletEnterProximityEvent(device, type, sourceDevice);
m_windowUnderPointer = window;
// The local coordinates may fall outside the window.
// Wait until the next update to send the enter event.
@ -583,12 +600,12 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin
m_windowUnderPointer = nullptr;
m_currentWindow = nullptr;
}
QWindowSystemInterface::handleTabletLeaveProximityEvent(device, type, pointerId);
QWindowSystemInterface::handleTabletLeaveProximityEvent(device, type, sourceDevice);
break;
case WM_POINTERDOWN:
case WM_POINTERUP:
case WM_POINTERUPDATE: {
QWindow *target = QGuiApplicationPrivate::tabletDevicePoint(pointerId).target; // Pass to window that grabbed it.
QWindow *target = QGuiApplicationPrivate::tabletDevicePoint(sourceDevice).target; // Pass to window that grabbed it.
if (!target && m_windowUnderPointer)
target = m_windowUnderPointer;
if (!target)
@ -607,7 +624,7 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin
QWindowSystemInterface::handleTabletEvent(target, localPos, hiResGlobalPos, device, type, mouseButtons,
pressure, xTilt, yTilt, tangentialPressure, rotation, z,
pointerId, keyModifiers);
sourceDevice, keyModifiers);
return false; // Allow mouse messages to be generated.
}
}
@ -681,7 +698,6 @@ bool QWindowsPointerHandler::translateMouseEvent(QWindow *window,
}
const Qt::KeyboardModifiers keyModifiers = QWindowsKeyMapper::queryKeyboardModifiers();
const Qt::MouseButtons mouseButtons = mouseButtonsFromKeyState(msg.wParam);
QWindow *currentWindowUnderPointer = getWindowUnderPointer(window, globalPos);
if (et == QtWindows::MouseWheelEvent)
@ -709,7 +725,8 @@ bool QWindowsPointerHandler::translateMouseEvent(QWindow *window,
const MouseEvent mouseEvent = eventFromMsg(msg);
if (mouseEvent.type >= QEvent::NonClientAreaMouseMove && mouseEvent.type <= QEvent::NonClientAreaMouseButtonDblClick) {
QWindowSystemInterface::handleFrameStrutMouseEvent(window, localPos, globalPos, mouseButtons,
const Qt::MouseButtons nonclientButtons = queryMouseButtons();
QWindowSystemInterface::handleFrameStrutMouseEvent(window, localPos, globalPos, nonclientButtons,
mouseEvent.button, mouseEvent.type, keyModifiers, source);
return false; // Allow further event processing
}
@ -725,6 +742,8 @@ bool QWindowsPointerHandler::translateMouseEvent(QWindow *window,
return true;
}
const Qt::MouseButtons mouseButtons = mouseButtonsFromKeyState(msg.wParam);
handleCaptureRelease(window, currentWindowUnderPointer, hwnd, mouseEvent.type, mouseButtons);
handleEnterLeave(window, currentWindowUnderPointer, globalPos);

View File

@ -270,7 +270,9 @@ void QGLXContext::init(QXcbScreen *screen, QPlatformOpenGLContext *share)
// ES does not support any format option
m_format.setOptions(QSurfaceFormat::FormatOptions());
}
// Robustness must match that of the shared context.
if (share && share->format().testOption(QSurfaceFormat::ResetNotification))
m_format.setOption(QSurfaceFormat::ResetNotification);
Q_ASSERT(glVersions.count() > 0);
for (int i = 0; !m_context && i < glVersions.count(); i++) {

View File

@ -69,6 +69,7 @@
QT_BEGIN_NAMESPACE
class QSystemTrayIconSys;
class QSystemTrayWatcher;
class QPlatformSystemTrayIcon;
class QToolButton;
class QLabel;
@ -90,6 +91,8 @@ public:
void showMessage_sys(const QString &title, const QString &msg, const QIcon &icon,
QSystemTrayIcon::MessageIcon msgIcon, int msecs);
void destroyIcon();
static bool isSystemTrayAvailable_sys();
static bool supportsMessages_sys();
@ -101,6 +104,7 @@ public:
QSystemTrayIconSys *sys;
QPlatformSystemTrayIcon *qpa_sys;
bool visible;
QSystemTrayWatcher *trayWatcher;
private:
void install_sys_qpa();

View File

@ -92,9 +92,6 @@ protected:
virtual void resizeEvent(QResizeEvent *) override;
virtual void moveEvent(QMoveEvent *) override;
private slots:
void systemTrayWindowChanged(QScreen *screen);
private:
QSystemTrayIcon *q;
};
@ -116,15 +113,6 @@ QSystemTrayIconSys::QSystemTrayIconSys(QSystemTrayIcon *qIn)
setMouseTracking(true);
}
void QSystemTrayIconSys::systemTrayWindowChanged(QScreen *)
{
if (!locateSystemTray()) {
QBalloonTip::hideBalloon();
hide(); // still no luck
destroy();
}
}
QRect QSystemTrayIconSys::globalGeometry() const
{
return QRect(mapToGlobal(QPoint(0, 0)), size());
@ -199,10 +187,41 @@ void QSystemTrayIconSys::resizeEvent(QResizeEvent *event)
}
////////////////////////////////////////////////////////////////////////////
class QSystemTrayWatcher: public QObject
{
Q_OBJECT
public:
QSystemTrayWatcher(QSystemTrayIcon *trayIcon)
: QObject(trayIcon)
, mTrayIcon(trayIcon)
{
// This code uses string-based syntax because we want to connect to a signal
// which is defined in XCB plugin - QXcbNativeInterface::systemTrayWindowChanged().
connect(qGuiApp->platformNativeInterface(), SIGNAL(systemTrayWindowChanged(QScreen*)),
this, SLOT(systemTrayWindowChanged(QScreen*)));
}
private slots:
void systemTrayWindowChanged(QScreen *)
{
auto icon = static_cast<QSystemTrayIconPrivate *>(QObjectPrivate::get(mTrayIcon));
icon->destroyIcon();
if (icon->visible && locateSystemTray()) {
icon->sys = new QSystemTrayIconSys(mTrayIcon);
icon->sys->show();
}
}
private:
QSystemTrayIcon *mTrayIcon = nullptr;
};
////////////////////////////////////////////////////////////////////////////
QSystemTrayIconPrivate::QSystemTrayIconPrivate()
: sys(0),
qpa_sys(QGuiApplicationPrivate::platformTheme()->createPlatformSystemTrayIcon()),
visible(false)
visible(false),
trayWatcher(nullptr)
{
}
@ -213,16 +232,21 @@ QSystemTrayIconPrivate::~QSystemTrayIconPrivate()
void QSystemTrayIconPrivate::install_sys()
{
Q_Q(QSystemTrayIcon);
if (qpa_sys) {
install_sys_qpa();
return;
}
Q_Q(QSystemTrayIcon);
if (!sys && locateSystemTray()) {
sys = new QSystemTrayIconSys(q);
QObject::connect(QGuiApplication::platformNativeInterface(), SIGNAL(systemTrayWindowChanged(QScreen*)),
sys, SLOT(systemTrayWindowChanged(QScreen*)));
sys->show();
if (!sys) {
if (!trayWatcher)
trayWatcher = new QSystemTrayWatcher(q);
if (locateSystemTray()) {
sys = new QSystemTrayIconSys(q);
sys->show();
}
}
}
@ -241,14 +265,21 @@ void QSystemTrayIconPrivate::remove_sys()
remove_sys_qpa();
return;
}
destroyIcon();
}
void QSystemTrayIconPrivate::destroyIcon()
{
if (!sys)
return;
QBalloonTip::hideBalloon();
sys->hide(); // this should do the trick, but...
delete sys; // wm may resize system tray only for DestroyEvents
sys = 0;
sys->hide();
delete sys;
sys = nullptr;
}
void QSystemTrayIconPrivate::updateIcon_sys()
{
if (qpa_sys) {