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) {
|
elsif (!$shadow) {
|
||||||
$pri_install_pfiles.= "$pri_install_iheader ";;
|
$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")
|
.":".($no_stamp ? "^" : "").fixPaths($oheader, "$out_basedir/include/$lib")
|
||||||
.$injection." " if ($shadow);
|
.$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
|
# libs-var, libs, in-paths, out-paths-var
|
||||||
defineTest(qtConfResolveLibs) {
|
defineTest(qtConfResolveLibs) {
|
||||||
ret = true
|
ret = true
|
||||||
@ -535,6 +546,7 @@ defineTest(qtConfResolveLibs) {
|
|||||||
out += $$l
|
out += $$l
|
||||||
} else: contains(l, "^-L.*") {
|
} else: contains(l, "^-L.*") {
|
||||||
lp = $$replace(l, "^-L", )
|
lp = $$replace(l, "^-L", )
|
||||||
|
gcc: lp = $$qtGccSysrootifiedPath($$lp)
|
||||||
!exists($$lp/.) {
|
!exists($$lp/.) {
|
||||||
qtLog("Library path $$val_escape(lp) is invalid.")
|
qtLog("Library path $$val_escape(lp) is invalid.")
|
||||||
ret = false
|
ret = false
|
||||||
@ -608,6 +620,7 @@ defineTest(qtConfResolveAllLibs) {
|
|||||||
# libs-var, in-paths, libs
|
# libs-var, in-paths, libs
|
||||||
defineTest(qtConfResolvePathLibs) {
|
defineTest(qtConfResolvePathLibs) {
|
||||||
ret = true
|
ret = true
|
||||||
|
gcc: 2 = $$qtGccSysrootifiedPaths($$2)
|
||||||
for (libdir, 2) {
|
for (libdir, 2) {
|
||||||
!exists($$libdir/.) {
|
!exists($$libdir/.) {
|
||||||
qtLog("Library path $$val_escape(libdir) is invalid.")
|
qtLog("Library path $$val_escape(libdir) is invalid.")
|
||||||
@ -658,6 +671,7 @@ defineReplace(qtConfGetTestIncludes) {
|
|||||||
# includes-var, in-paths, test-object-var
|
# includes-var, in-paths, test-object-var
|
||||||
defineTest(qtConfResolvePathIncs) {
|
defineTest(qtConfResolvePathIncs) {
|
||||||
ret = true
|
ret = true
|
||||||
|
gcc: 2 = $$qtGccSysrootifiedPaths($$2)
|
||||||
for (incdir, 2) {
|
for (incdir, 2) {
|
||||||
!exists($$incdir/.) {
|
!exists($$incdir/.) {
|
||||||
qtLog("Include path $$val_escape(incdir) is invalid.")
|
qtLog("Include path $$val_escape(incdir) is invalid.")
|
||||||
|
@ -23,7 +23,7 @@ load(qt_build_paths)
|
|||||||
QMAKE_SYNCQT += -module $$mod
|
QMAKE_SYNCQT += -module $$mod
|
||||||
QMAKE_SYNCQT += \
|
QMAKE_SYNCQT += \
|
||||||
-version $$VERSION -outdir $$system_quote($$MODULE_BASE_OUTDIR) \
|
-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)
|
!silent: message($$QMAKE_SYNCQT)
|
||||||
system($$QMAKE_SYNCQT)|error("Failed to run: $$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}
|
The value of this variable is typically handled by qmake or \l{#QMAKESPEC}{qmake.conf}
|
||||||
and rarely needs to be modified.
|
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
|
\target QMAKE_CFLAGS_SHLIB
|
||||||
\section1 QMAKE_CFLAGS_SHLIB
|
\section1 QMAKE_CFLAGS_SHLIB
|
||||||
|
|
||||||
@ -1683,6 +1691,14 @@
|
|||||||
The value of this variable is typically handled by
|
The value of this variable is typically handled by
|
||||||
qmake or \l{#QMAKESPEC}{qmake.conf} and rarely needs to be modified.
|
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
|
\target QMAKE_CXXFLAGS_SHLIB
|
||||||
\section1 QMAKE_CXXFLAGS_SHLIB
|
\section1 QMAKE_CXXFLAGS_SHLIB
|
||||||
|
|
||||||
@ -2063,6 +2079,12 @@
|
|||||||
The value of this variable is typically handled by
|
The value of this variable is typically handled by
|
||||||
qmake or \l{#QMAKESPEC}{qmake.conf} and rarely needs to be modified.
|
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
|
\section1 QMAKE_LFLAGS_APP
|
||||||
|
|
||||||
Specifies the linker flags for building applications.
|
Specifies the linker flags for building applications.
|
||||||
|
@ -142,6 +142,7 @@ const char _InterfaceIdentifierFileName[] = "InterfaceIdentifierFileName";
|
|||||||
const char _IntermediateDirectory[] = "IntermediateDirectory";
|
const char _IntermediateDirectory[] = "IntermediateDirectory";
|
||||||
const char _KeyContainer[] = "KeyContainer";
|
const char _KeyContainer[] = "KeyContainer";
|
||||||
const char _KeyFile[] = "KeyFile";
|
const char _KeyFile[] = "KeyFile";
|
||||||
|
const char _LanguageStandard[] = "LanguageStandard";
|
||||||
const char _LargeAddressAware[] = "LargeAddressAware";
|
const char _LargeAddressAware[] = "LargeAddressAware";
|
||||||
const char _LinkDLL[] = "LinkDLL";
|
const char _LinkDLL[] = "LinkDLL";
|
||||||
const char _LinkErrorReporting[] = "LinkErrorReporting";
|
const char _LinkErrorReporting[] = "LinkErrorReporting";
|
||||||
@ -1477,6 +1478,7 @@ void VCXProjectWriter::write(XmlOutput &xml, const VCCLCompilerTool &tool)
|
|||||||
<< attrTagT(_IntrinsicFunctions, tool.EnableIntrinsicFunctions)
|
<< attrTagT(_IntrinsicFunctions, tool.EnableIntrinsicFunctions)
|
||||||
<< attrTagT(_MinimalRebuild, tool.MinimalRebuild)
|
<< attrTagT(_MinimalRebuild, tool.MinimalRebuild)
|
||||||
<< attrTagT(_MultiProcessorCompilation, tool.MultiProcessorCompilation)
|
<< attrTagT(_MultiProcessorCompilation, tool.MultiProcessorCompilation)
|
||||||
|
<< attrTagS(_LanguageStandard, tool.LanguageStandard)
|
||||||
<< attrTagS(_ObjectFileName, tool.ObjectFile)
|
<< attrTagS(_ObjectFileName, tool.ObjectFile)
|
||||||
<< attrTagT(_OmitDefaultLibName, tool.OmitDefaultLibName)
|
<< attrTagT(_OmitDefaultLibName, tool.OmitDefaultLibName)
|
||||||
<< attrTagT(_OmitFramePointers, tool.OmitFramePointers)
|
<< attrTagT(_OmitFramePointers, tool.OmitFramePointers)
|
||||||
|
@ -1146,6 +1146,14 @@ bool VCCLCompilerTool::parseOption(const char* option)
|
|||||||
ShowIncludes = _True;
|
ShowIncludes = _True;
|
||||||
break;
|
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;
|
found = false; break;
|
||||||
case 'u':
|
case 'u':
|
||||||
if (!second)
|
if (!second)
|
||||||
|
@ -526,6 +526,7 @@ public:
|
|||||||
triState ImproveFloatingPointConsistency;
|
triState ImproveFloatingPointConsistency;
|
||||||
inlineExpansionOption InlineFunctionExpansion;
|
inlineExpansionOption InlineFunctionExpansion;
|
||||||
triState KeepComments;
|
triState KeepComments;
|
||||||
|
QString LanguageStandard;
|
||||||
triState MinimalRebuild;
|
triState MinimalRebuild;
|
||||||
QString ObjectFile;
|
QString ObjectFile;
|
||||||
triState OmitDefaultLibName;
|
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;
|
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)
|
Display::Display(EGLenum platform, EGLNativeDisplayType displayId, Device *eglDevice)
|
||||||
: mImplementation(nullptr),
|
: mImplementation(nullptr),
|
||||||
mDisplayId(displayId),
|
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 *GetDisplayFromDevice(Device *device, const AttributeMap &attribMap);
|
||||||
static Display *GetDisplayFromNativeDisplay(EGLNativeDisplayType nativeDisplay,
|
static Display *GetDisplayFromNativeDisplay(EGLNativeDisplayType nativeDisplay,
|
||||||
const AttributeMap &attribMap);
|
const AttributeMap &attribMap);
|
||||||
|
static void CleanupDisplays();
|
||||||
|
|
||||||
static const ClientExtensions &GetClientExtensions();
|
static const ClientExtensions &GetClientExtensions();
|
||||||
static const std::string &GetClientExtensionString();
|
static const std::string &GetClientExtensionString();
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "common/tls.h"
|
#include "common/tls.h"
|
||||||
|
|
||||||
#include "libANGLE/Thread.h"
|
#include "libANGLE/Thread.h"
|
||||||
|
#include "libANGLE/Display.h"
|
||||||
|
|
||||||
namespace gl
|
namespace gl
|
||||||
{
|
{
|
||||||
@ -140,6 +141,7 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE, DWORD reason, LPVOID)
|
|||||||
return static_cast<BOOL>(egl::DeallocateCurrentThread());
|
return static_cast<BOOL>(egl::DeallocateCurrentThread());
|
||||||
|
|
||||||
case DLL_PROCESS_DETACH:
|
case DLL_PROCESS_DETACH:
|
||||||
|
egl::Display::CleanupDisplays();
|
||||||
return static_cast<BOOL>(egl::TerminateProcess());
|
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
|
\overload
|
||||||
|
|
||||||
Generates one random 32-bit quantity in the range between 0 (inclusive) and
|
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
|
\snippet code/src_corelib_global_qrandom.cpp 14
|
||||||
|
|
||||||
|
|
||||||
Note that this function cannot be used to obtain values in the full 32-bit
|
Note that this function cannot be used to obtain values in the full 32-bit
|
||||||
range of quint32. Instead, use generate().
|
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
|
\overload
|
||||||
|
|
||||||
Generates one random 32-bit quantity in the range between \a lowest
|
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::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.
|
initialize(paintDevice);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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();
|
QPaintEngine *paintEngine = painter->paintEngine();
|
||||||
|
|
||||||
@ -414,51 +409,68 @@ QMacCGContext::QMacCGContext(QPainter *painter) : context(0)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int devType = painter->device()->devType();
|
if (paintEngine->type() != QPaintEngine::Raster) {
|
||||||
if (paintEngine->type() == QPaintEngine::Raster
|
qWarning() << "QMacCGContext:: Unsupported paint engine type" << paintEngine->type();
|
||||||
&& (devType == QInternal::Widget ||
|
return;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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
|
QT_END_NAMESPACE
|
||||||
|
@ -51,6 +51,8 @@
|
|||||||
// We mean it.
|
// We mean it.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include <QtCore/private/qcore_mac_p.h>
|
||||||
|
|
||||||
#include <QtGui/private/qtguiglobal_p.h>
|
#include <QtGui/private/qtguiglobal_p.h>
|
||||||
#include <QtGui/qregion.h>
|
#include <QtGui/qregion.h>
|
||||||
#include <QtGui/qpalette.h>
|
#include <QtGui/qpalette.h>
|
||||||
@ -89,38 +91,16 @@ Q_GUI_EXPORT QBrush qt_mac_toQBrush(CGColorRef color);
|
|||||||
class Q_GUI_EXPORT QMacCGContext
|
class Q_GUI_EXPORT QMacCGContext
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
inline QMacCGContext() { context = 0; }
|
QMacCGContext() = default;
|
||||||
QMacCGContext(QPaintDevice *pdev);
|
QMacCGContext(QPaintDevice *pdev);
|
||||||
QMacCGContext(QPainter *p);
|
QMacCGContext(QPainter *p);
|
||||||
inline QMacCGContext(CGContextRef cg, bool takeOwnership = false) {
|
|
||||||
context = cg;
|
operator CGContextRef() { return context; }
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CGContextRef context;
|
void initialize(QPaintDevice *paintDevice);
|
||||||
|
void initialize(const QImage *, QPainter *painter = nullptr);
|
||||||
|
QCFType<CGContextRef> context;
|
||||||
};
|
};
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
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 LocalHost The IPv4 localhost address. Equivalent to QHostAddress("127.0.0.1").
|
||||||
\value LocalHostIPv6 The IPv6 localhost address. Equivalent to QHostAddress("::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 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 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 interaces.
|
\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.
|
\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());
|
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)
|
QOpenGLTextureBlitter *blitter, QMatrix4x4 *rotationMatrix)
|
||||||
{
|
{
|
||||||
const QRect clipRect = textures->clipRect(idx);
|
const QRect clipRect = textures->clipRect(idx);
|
||||||
if (clipRect.isEmpty())
|
if (clipRect.isEmpty())
|
||||||
return;
|
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 clippedRectInWindow = rectInWindow & clipRect.translated(rectInWindow.topLeft());
|
||||||
const QRect srcRect = toBottomLeftRect(clipRect, rectInWindow.height());
|
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());
|
const QRect targetWindowRect(QPoint(0, 0), m_targetWindow->geometry().size());
|
||||||
float currentOpacity = 1.0f;
|
float currentOpacity = 1.0f;
|
||||||
BlendStateBinder blend;
|
BlendStateBinder blend;
|
||||||
|
const QRect sourceWindowRect = window->sourceWindow()->geometry();
|
||||||
for (int i = 0; i < textures->count(); ++i) {
|
for (int i = 0; i < textures->count(); ++i) {
|
||||||
uint textureId = textures->textureId(i);
|
uint textureId = textures->textureId(i);
|
||||||
const float opacity = window->sourceWindow()->opacity();
|
const float opacity = window->sourceWindow()->opacity();
|
||||||
@ -243,16 +244,16 @@ void QOpenGLCompositor::render(QOpenGLCompositorWindow *window)
|
|||||||
target = m_rotationMatrix * target;
|
target = m_rotationMatrix * target;
|
||||||
m_blitter.blit(textureId, target, QOpenGLTextureBlitter::OriginTopLeft);
|
m_blitter.blit(textureId, target, QOpenGLTextureBlitter::OriginTopLeft);
|
||||||
} else if (!textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop)) {
|
} 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);
|
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) {
|
for (int i = 0; i < textures->count(); ++i) {
|
||||||
if (textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop)) {
|
if (textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop)) {
|
||||||
blend.set(true);
|
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
|
QRegion dirtyRegion; // In unscaled coordinates
|
||||||
QImage *asImage();
|
QImage *asImage();
|
||||||
|
qreal devicePixelRatio() const { return m_devicePixelRatio; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
qreal m_devicePixelRatio;
|
qreal m_devicePixelRatio;
|
||||||
|
@ -460,12 +460,29 @@ void QCALayerBackingStore::flush(QWindow *flushedWindow, const QRegion ®ion,
|
|||||||
NSView *backingStoreView = static_cast<QCocoaWindow *>(window()->handle())->view();
|
NSView *backingStoreView = static_cast<QCocoaWindow *>(window()->handle())->view();
|
||||||
NSView *flushedView = static_cast<QCocoaWindow *>(flushedWindow->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();
|
id backBufferSurface = (__bridge id)m_buffers.back()->surface();
|
||||||
if (flushedView.layer.contents == backBufferSurface) {
|
if (flushedView.layer.contents == backBufferSurface) {
|
||||||
// We've managed to paint to the back buffer again before Core Animation had time
|
// 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.
|
// to flush the transaction and persist the layer changes to the window server, or
|
||||||
// The layer already knows about the back buffer, and we don't need to re-apply
|
// we've been asked to flush without painting anything. The layer already knows about
|
||||||
// it to pick up the surface changes, so bail out early.
|
// 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
|
qCInfo(lcQpaBackingStore).nospace() << "Skipping flush of " << flushedView
|
||||||
<< ", layer already reflects back buffer";
|
<< ", layer already reflects back buffer";
|
||||||
return;
|
return;
|
||||||
|
@ -199,6 +199,10 @@ QPlatformWindow *QEglFSIntegration::createPlatformWindow(QWindow *window) const
|
|||||||
QEglFSWindow *w = qt_egl_device_integration()->createWindow(window);
|
QEglFSWindow *w = qt_egl_device_integration()->createWindow(window);
|
||||||
w->create();
|
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
|
// Activate only the window for the primary screen to make input work
|
||||||
if (window->type() != Qt::ToolTip && window->screen() == QGuiApplication::primaryScreen())
|
if (window->type() != Qt::ToolTip && window->screen() == QGuiApplication::primaryScreen())
|
||||||
w->requestActivateWindow();
|
w->requestActivateWindow();
|
||||||
|
@ -167,6 +167,9 @@ void QEglFSWindow::create()
|
|||||||
|
|
||||||
void QEglFSWindow::destroy()
|
void QEglFSWindow::destroy()
|
||||||
{
|
{
|
||||||
|
if (!m_flags.testFlag(Created))
|
||||||
|
return; // already destroyed
|
||||||
|
|
||||||
#ifndef QT_NO_OPENGL
|
#ifndef QT_NO_OPENGL
|
||||||
QOpenGLCompositor::instance()->removeWindow(this);
|
QOpenGLCompositor::instance()->removeWindow(this);
|
||||||
#endif
|
#endif
|
||||||
|
@ -55,6 +55,9 @@ public:
|
|||||||
: QEglFSWindow(w),
|
: QEglFSWindow(w),
|
||||||
m_integration(integration)
|
m_integration(integration)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
~QEglFSKmsGbmWindow() { destroy(); }
|
||||||
|
|
||||||
void resetSurface() override;
|
void resetSurface() override;
|
||||||
void invalidateSurface() override;
|
void invalidateSurface() override;
|
||||||
|
|
||||||
|
@ -116,6 +116,8 @@ public:
|
|||||||
, m_egl_stream(EGL_NO_STREAM_KHR)
|
, m_egl_stream(EGL_NO_STREAM_KHR)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
~QEglFSKmsEglDeviceWindow() { destroy(); }
|
||||||
|
|
||||||
void invalidateSurface() override;
|
void invalidateSurface() override;
|
||||||
void resetSurface() override;
|
void resetSurface() override;
|
||||||
|
|
||||||
|
@ -205,6 +205,9 @@ public:
|
|||||||
: QEglFSWindow(w)
|
: QEglFSWindow(w)
|
||||||
, m_integration(integration)
|
, m_integration(integration)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
~QEglFSKmsVsp2Window() { destroy(); }
|
||||||
|
|
||||||
void resetSurface() override;
|
void resetSurface() override;
|
||||||
void invalidateSurface() override;
|
void invalidateSurface() override;
|
||||||
const QEglFSKmsVsp2Integration *m_integration;
|
const QEglFSKmsVsp2Integration *m_integration;
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
|
|
||||||
#include <QtCore/qurl.h>
|
#include <QtCore/qurl.h>
|
||||||
#include <QtCore/qmimedata.h>
|
#include <QtCore/qmimedata.h>
|
||||||
|
#include "qwindowsmime.h"
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
@ -48,8 +49,9 @@ QT_BEGIN_NAMESPACE
|
|||||||
\class QWindowsDropDataObject
|
\class QWindowsDropDataObject
|
||||||
\brief QWindowsOleDataObject subclass specialized for handling Drag&Drop.
|
\brief QWindowsOleDataObject subclass specialized for handling Drag&Drop.
|
||||||
|
|
||||||
Only allows "text/uri-list" data to be exported as CF_HDROP, to allow dropped
|
Prevents "text/uri-list" data for local files from being exported as text
|
||||||
files to be attached to Office applications (instead of adding an URL link).
|
or URLs, to allow dropped files to be attached to Office applications
|
||||||
|
(instead of creating local hyperlinks).
|
||||||
|
|
||||||
\internal
|
\internal
|
||||||
\ingroup qt-lighthouse-win
|
\ingroup qt-lighthouse-win
|
||||||
@ -80,14 +82,22 @@ QWindowsDropDataObject::QueryGetData(LPFORMATETC pformatetc)
|
|||||||
return QWindowsOleDataObject::QueryGetData(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
|
bool QWindowsDropDataObject::shouldIgnore(LPFORMATETC pformatetc) const
|
||||||
{
|
{
|
||||||
QMimeData *dropData = mimeData();
|
QMimeData *dropData = mimeData();
|
||||||
|
|
||||||
if (dropData && dropData->hasFormat(QStringLiteral("text/uri-list")) && (pformatetc->cfFormat != CF_HDROP)) {
|
if (dropData && dropData->formats().size() == 1 && dropData->hasUrls()) {
|
||||||
QList<QUrl> urls = dropData->urls();
|
QString formatName = QWindowsMimeConverter::clipboardFormatName(pformatetc->cfFormat);
|
||||||
return std::any_of(urls.cbegin(), urls.cend(), [] (const QUrl &u) { return u.isLocalFile(); });
|
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;
|
return false;
|
||||||
|
@ -879,21 +879,16 @@ bool QWindowsKeyMapper::translateMultimediaKeyEventInternal(QWindow *window, con
|
|||||||
#if defined(WM_APPCOMMAND)
|
#if defined(WM_APPCOMMAND)
|
||||||
const int cmd = GET_APPCOMMAND_LPARAM(msg.lParam);
|
const int cmd = GET_APPCOMMAND_LPARAM(msg.lParam);
|
||||||
// QTBUG-57198, do not send mouse-synthesized commands as key events in addition
|
// QTBUG-57198, do not send mouse-synthesized commands as key events in addition
|
||||||
|
bool skipPressRelease = false;
|
||||||
switch (GET_DEVICE_LPARAM(msg.lParam)) {
|
switch (GET_DEVICE_LPARAM(msg.lParam)) {
|
||||||
case FAPPCOMMAND_MOUSE:
|
case FAPPCOMMAND_MOUSE:
|
||||||
return false;
|
return false;
|
||||||
case FAPPCOMMAND_KEY:
|
case FAPPCOMMAND_KEY:
|
||||||
// QTBUG-62838, swallow WM_KEYDOWN, WM_KEYUP for commands that are
|
// QTBUG-62838, use WM_KEYDOWN/WM_KEYUP for commands that are reflected
|
||||||
// reflected in VK(s) like VK_MEDIA_NEXT_TRACK. Don't do that for
|
// in VK(s) like VK_MEDIA_NEXT_TRACK, to get correct codes and autorepeat.
|
||||||
// APPCOMMAND_BROWSER_HOME as that one does not trigger two events
|
// Don't do that for APPCOMMAND_BROWSER_HOME as that one does not trigger two events.
|
||||||
if (cmd != APPCOMMAND_BROWSER_HOME) {
|
if (cmd != APPCOMMAND_BROWSER_HOME)
|
||||||
MSG peekedMsg;
|
skipPressRelease = true;
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -908,7 +903,8 @@ bool QWindowsKeyMapper::translateMultimediaKeyEventInternal(QWindow *window, con
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
const int qtKey = int(CmdTbl[cmd]);
|
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,
|
// 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.
|
// the keys are not passed to the active media player.
|
||||||
# if QT_CONFIG(shortcut)
|
# if QT_CONFIG(shortcut)
|
||||||
|
@ -250,6 +250,23 @@ static Qt::MouseButtons mouseButtonsFromKeyState(WPARAM keyState)
|
|||||||
return result;
|
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)
|
static QWindow *getWindowUnderPointer(QWindow *window, QPoint globalPos)
|
||||||
{
|
{
|
||||||
QWindow *currentWindowUnderPointer = QWindowsScreen::windowAt(globalPos, CWP_SKIPINVISIBLE | CWP_SKIPTRANSPARENT);
|
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))
|
if (!QWindowsContext::user32dll.getPointerDeviceRects(penInfo->pointerInfo.sourceDevice, &pRect, &dRect))
|
||||||
return false;
|
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 globalPos = QPoint(penInfo->pointerInfo.ptPixelLocation.x, penInfo->pointerInfo.ptPixelLocation.y);
|
||||||
const QPoint localPos = QWindowsGeometryHint::mapFromGlobal(hwnd, globalPos);
|
const QPoint localPos = QWindowsGeometryHint::mapFromGlobal(hwnd, globalPos);
|
||||||
const QPointF hiResGlobalPos = QPointF(dRect.left + qreal(penInfo->pointerInfo.ptHimetricLocation.x - pRect.left)
|
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)
|
if (QWindowsContext::verbose > 1)
|
||||||
qCDebug(lcQpaEvents).noquote().nospace() << showbase
|
qCDebug(lcQpaEvents).noquote().nospace() << showbase
|
||||||
<< __FUNCTION__ << " pointerId=" << pointerId
|
<< __FUNCTION__ << " sourceDevice=" << sourceDevice
|
||||||
<< " globalPos=" << globalPos << " localPos=" << localPos << " hiResGlobalPos=" << hiResGlobalPos
|
<< " globalPos=" << globalPos << " localPos=" << localPos << " hiResGlobalPos=" << hiResGlobalPos
|
||||||
<< " message=" << hex << msg.message
|
<< " message=" << hex << msg.message
|
||||||
<< " flags=" << hex << penInfo->pointerInfo.pointerFlags;
|
<< " flags=" << hex << penInfo->pointerInfo.pointerFlags;
|
||||||
@ -570,7 +587,7 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin
|
|||||||
|
|
||||||
switch (msg.message) {
|
switch (msg.message) {
|
||||||
case WM_POINTERENTER: {
|
case WM_POINTERENTER: {
|
||||||
QWindowSystemInterface::handleTabletEnterProximityEvent(device, type, pointerId);
|
QWindowSystemInterface::handleTabletEnterProximityEvent(device, type, sourceDevice);
|
||||||
m_windowUnderPointer = window;
|
m_windowUnderPointer = window;
|
||||||
// The local coordinates may fall outside the window.
|
// The local coordinates may fall outside the window.
|
||||||
// Wait until the next update to send the enter event.
|
// 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_windowUnderPointer = nullptr;
|
||||||
m_currentWindow = nullptr;
|
m_currentWindow = nullptr;
|
||||||
}
|
}
|
||||||
QWindowSystemInterface::handleTabletLeaveProximityEvent(device, type, pointerId);
|
QWindowSystemInterface::handleTabletLeaveProximityEvent(device, type, sourceDevice);
|
||||||
break;
|
break;
|
||||||
case WM_POINTERDOWN:
|
case WM_POINTERDOWN:
|
||||||
case WM_POINTERUP:
|
case WM_POINTERUP:
|
||||||
case WM_POINTERUPDATE: {
|
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)
|
if (!target && m_windowUnderPointer)
|
||||||
target = m_windowUnderPointer;
|
target = m_windowUnderPointer;
|
||||||
if (!target)
|
if (!target)
|
||||||
@ -607,7 +624,7 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin
|
|||||||
|
|
||||||
QWindowSystemInterface::handleTabletEvent(target, localPos, hiResGlobalPos, device, type, mouseButtons,
|
QWindowSystemInterface::handleTabletEvent(target, localPos, hiResGlobalPos, device, type, mouseButtons,
|
||||||
pressure, xTilt, yTilt, tangentialPressure, rotation, z,
|
pressure, xTilt, yTilt, tangentialPressure, rotation, z,
|
||||||
pointerId, keyModifiers);
|
sourceDevice, keyModifiers);
|
||||||
return false; // Allow mouse messages to be generated.
|
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::KeyboardModifiers keyModifiers = QWindowsKeyMapper::queryKeyboardModifiers();
|
||||||
const Qt::MouseButtons mouseButtons = mouseButtonsFromKeyState(msg.wParam);
|
|
||||||
QWindow *currentWindowUnderPointer = getWindowUnderPointer(window, globalPos);
|
QWindow *currentWindowUnderPointer = getWindowUnderPointer(window, globalPos);
|
||||||
|
|
||||||
if (et == QtWindows::MouseWheelEvent)
|
if (et == QtWindows::MouseWheelEvent)
|
||||||
@ -709,7 +725,8 @@ bool QWindowsPointerHandler::translateMouseEvent(QWindow *window,
|
|||||||
const MouseEvent mouseEvent = eventFromMsg(msg);
|
const MouseEvent mouseEvent = eventFromMsg(msg);
|
||||||
|
|
||||||
if (mouseEvent.type >= QEvent::NonClientAreaMouseMove && mouseEvent.type <= QEvent::NonClientAreaMouseButtonDblClick) {
|
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);
|
mouseEvent.button, mouseEvent.type, keyModifiers, source);
|
||||||
return false; // Allow further event processing
|
return false; // Allow further event processing
|
||||||
}
|
}
|
||||||
@ -725,6 +742,8 @@ bool QWindowsPointerHandler::translateMouseEvent(QWindow *window,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Qt::MouseButtons mouseButtons = mouseButtonsFromKeyState(msg.wParam);
|
||||||
|
|
||||||
handleCaptureRelease(window, currentWindowUnderPointer, hwnd, mouseEvent.type, mouseButtons);
|
handleCaptureRelease(window, currentWindowUnderPointer, hwnd, mouseEvent.type, mouseButtons);
|
||||||
handleEnterLeave(window, currentWindowUnderPointer, globalPos);
|
handleEnterLeave(window, currentWindowUnderPointer, globalPos);
|
||||||
|
|
||||||
|
@ -270,7 +270,9 @@ void QGLXContext::init(QXcbScreen *screen, QPlatformOpenGLContext *share)
|
|||||||
// ES does not support any format option
|
// ES does not support any format option
|
||||||
m_format.setOptions(QSurfaceFormat::FormatOptions());
|
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);
|
Q_ASSERT(glVersions.count() > 0);
|
||||||
|
|
||||||
for (int i = 0; !m_context && i < glVersions.count(); i++) {
|
for (int i = 0; !m_context && i < glVersions.count(); i++) {
|
||||||
|
@ -69,6 +69,7 @@
|
|||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class QSystemTrayIconSys;
|
class QSystemTrayIconSys;
|
||||||
|
class QSystemTrayWatcher;
|
||||||
class QPlatformSystemTrayIcon;
|
class QPlatformSystemTrayIcon;
|
||||||
class QToolButton;
|
class QToolButton;
|
||||||
class QLabel;
|
class QLabel;
|
||||||
@ -90,6 +91,8 @@ public:
|
|||||||
void showMessage_sys(const QString &title, const QString &msg, const QIcon &icon,
|
void showMessage_sys(const QString &title, const QString &msg, const QIcon &icon,
|
||||||
QSystemTrayIcon::MessageIcon msgIcon, int msecs);
|
QSystemTrayIcon::MessageIcon msgIcon, int msecs);
|
||||||
|
|
||||||
|
void destroyIcon();
|
||||||
|
|
||||||
static bool isSystemTrayAvailable_sys();
|
static bool isSystemTrayAvailable_sys();
|
||||||
static bool supportsMessages_sys();
|
static bool supportsMessages_sys();
|
||||||
|
|
||||||
@ -101,6 +104,7 @@ public:
|
|||||||
QSystemTrayIconSys *sys;
|
QSystemTrayIconSys *sys;
|
||||||
QPlatformSystemTrayIcon *qpa_sys;
|
QPlatformSystemTrayIcon *qpa_sys;
|
||||||
bool visible;
|
bool visible;
|
||||||
|
QSystemTrayWatcher *trayWatcher;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void install_sys_qpa();
|
void install_sys_qpa();
|
||||||
|
@ -92,9 +92,6 @@ protected:
|
|||||||
virtual void resizeEvent(QResizeEvent *) override;
|
virtual void resizeEvent(QResizeEvent *) override;
|
||||||
virtual void moveEvent(QMoveEvent *) override;
|
virtual void moveEvent(QMoveEvent *) override;
|
||||||
|
|
||||||
private slots:
|
|
||||||
void systemTrayWindowChanged(QScreen *screen);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QSystemTrayIcon *q;
|
QSystemTrayIcon *q;
|
||||||
};
|
};
|
||||||
@ -116,15 +113,6 @@ QSystemTrayIconSys::QSystemTrayIconSys(QSystemTrayIcon *qIn)
|
|||||||
setMouseTracking(true);
|
setMouseTracking(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QSystemTrayIconSys::systemTrayWindowChanged(QScreen *)
|
|
||||||
{
|
|
||||||
if (!locateSystemTray()) {
|
|
||||||
QBalloonTip::hideBalloon();
|
|
||||||
hide(); // still no luck
|
|
||||||
destroy();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QRect QSystemTrayIconSys::globalGeometry() const
|
QRect QSystemTrayIconSys::globalGeometry() const
|
||||||
{
|
{
|
||||||
return QRect(mapToGlobal(QPoint(0, 0)), size());
|
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()
|
QSystemTrayIconPrivate::QSystemTrayIconPrivate()
|
||||||
: sys(0),
|
: sys(0),
|
||||||
qpa_sys(QGuiApplicationPrivate::platformTheme()->createPlatformSystemTrayIcon()),
|
qpa_sys(QGuiApplicationPrivate::platformTheme()->createPlatformSystemTrayIcon()),
|
||||||
visible(false)
|
visible(false),
|
||||||
|
trayWatcher(nullptr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,16 +232,21 @@ QSystemTrayIconPrivate::~QSystemTrayIconPrivate()
|
|||||||
|
|
||||||
void QSystemTrayIconPrivate::install_sys()
|
void QSystemTrayIconPrivate::install_sys()
|
||||||
{
|
{
|
||||||
|
Q_Q(QSystemTrayIcon);
|
||||||
|
|
||||||
if (qpa_sys) {
|
if (qpa_sys) {
|
||||||
install_sys_qpa();
|
install_sys_qpa();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Q_Q(QSystemTrayIcon);
|
|
||||||
if (!sys && locateSystemTray()) {
|
if (!sys) {
|
||||||
sys = new QSystemTrayIconSys(q);
|
if (!trayWatcher)
|
||||||
QObject::connect(QGuiApplication::platformNativeInterface(), SIGNAL(systemTrayWindowChanged(QScreen*)),
|
trayWatcher = new QSystemTrayWatcher(q);
|
||||||
sys, SLOT(systemTrayWindowChanged(QScreen*)));
|
|
||||||
sys->show();
|
if (locateSystemTray()) {
|
||||||
|
sys = new QSystemTrayIconSys(q);
|
||||||
|
sys->show();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -241,14 +265,21 @@ void QSystemTrayIconPrivate::remove_sys()
|
|||||||
remove_sys_qpa();
|
remove_sys_qpa();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
destroyIcon();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QSystemTrayIconPrivate::destroyIcon()
|
||||||
|
{
|
||||||
if (!sys)
|
if (!sys)
|
||||||
return;
|
return;
|
||||||
QBalloonTip::hideBalloon();
|
QBalloonTip::hideBalloon();
|
||||||
sys->hide(); // this should do the trick, but...
|
sys->hide();
|
||||||
delete sys; // wm may resize system tray only for DestroyEvents
|
delete sys;
|
||||||
sys = 0;
|
sys = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void QSystemTrayIconPrivate::updateIcon_sys()
|
void QSystemTrayIconPrivate::updateIcon_sys()
|
||||||
{
|
{
|
||||||
if (qpa_sys) {
|
if (qpa_sys) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user