Merge remote-tracking branch 'origin/5.12' into 5.13
Change-Id: I26da00aa71b0f0b91c9bfb4a9e8550345ee62875
This commit is contained in:
commit
cb10ec56f7
@ -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
82
dist/changes-5.12.3
vendored
Normal 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.
|
||||
|
@ -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.")
|
||||
|
@ -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")
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -526,6 +526,7 @@ public:
|
||||
triState ImproveFloatingPointConsistency;
|
||||
inlineExpansionOption InlineFunctionExpansion;
|
||||
triState KeepComments;
|
||||
QString LanguageStandard;
|
||||
triState MinimalRebuild;
|
||||
QString ObjectFile;
|
||||
triState OmitDefaultLibName;
|
||||
|
17
src/3rdparty/angle/src/libANGLE/Display.cpp
vendored
17
src/3rdparty/angle/src/libANGLE/Display.cpp
vendored
@ -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),
|
||||
|
1
src/3rdparty/angle/src/libANGLE/Display.h
vendored
1
src/3rdparty/angle/src/libANGLE/Display.h
vendored
@ -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();
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 ©) : 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 ©) {
|
||||
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
|
||||
|
@ -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.
|
||||
*/
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -93,6 +93,7 @@ private:
|
||||
|
||||
QRegion dirtyRegion; // In unscaled coordinates
|
||||
QImage *asImage();
|
||||
qreal devicePixelRatio() const { return m_devicePixelRatio; }
|
||||
|
||||
private:
|
||||
qreal m_devicePixelRatio;
|
||||
|
@ -460,12 +460,29 @@ void QCALayerBackingStore::flush(QWindow *flushedWindow, const QRegion ®ion,
|
||||
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;
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -55,6 +55,9 @@ public:
|
||||
: QEglFSWindow(w),
|
||||
m_integration(integration)
|
||||
{ }
|
||||
|
||||
~QEglFSKmsGbmWindow() { destroy(); }
|
||||
|
||||
void resetSurface() override;
|
||||
void invalidateSurface() override;
|
||||
|
||||
|
@ -116,6 +116,8 @@ public:
|
||||
, m_egl_stream(EGL_NO_STREAM_KHR)
|
||||
{ }
|
||||
|
||||
~QEglFSKmsEglDeviceWindow() { destroy(); }
|
||||
|
||||
void invalidateSurface() override;
|
||||
void resetSurface() override;
|
||||
|
||||
|
@ -205,6 +205,9 @@ public:
|
||||
: QEglFSWindow(w)
|
||||
, m_integration(integration)
|
||||
{}
|
||||
|
||||
~QEglFSKmsVsp2Window() { destroy(); }
|
||||
|
||||
void resetSurface() override;
|
||||
void invalidateSurface() override;
|
||||
const QEglFSKmsVsp2Integration *m_integration;
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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++) {
|
||||
|
@ -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();
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user