Merge remote-tracking branch 'origin/5.12' into 5.13
Conflicts: src/gui/kernel/qplatformintegration.cpp src/gui/kernel/qplatformintegration.h src/plugins/platforms/wasm/qwasmintegration.cpp src/plugins/platforms/xcb/qxcbconnection_screens.cpp Change-Id: I15063d42e9a1e226d9d2d2d372f75141b84c5c1b
This commit is contained in:
commit
6893919b0c
105
dist/changes-5.12.2
vendored
Normal file
105
dist/changes-5.12.2
vendored
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
Qt 5.12.2 is a bug-fix release. It maintains both forward and backward
|
||||||
|
compatibility (source and binary) with Qt 5.12.0 through 5.12.1.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
****************************************************************************
|
||||||
|
* Important Behavior Changes *
|
||||||
|
****************************************************************************
|
||||||
|
|
||||||
|
- QtTestLib:
|
||||||
|
* [QTBUG-72928] Blacklisting of tests will be taken into account for
|
||||||
|
XPASS and XFAIL. A blacklisted test that causes an XPASS will no
|
||||||
|
longer be a fail.
|
||||||
|
|
||||||
|
****************************************************************************
|
||||||
|
* QtCore *
|
||||||
|
****************************************************************************
|
||||||
|
|
||||||
|
- [QTBUG-72885] Fixed a number of warnings with Clang or Clang-Tidy in
|
||||||
|
Qt headers related to alignment of Qt private classes.
|
||||||
|
|
||||||
|
- QDate, QTime and QDateTime;
|
||||||
|
* [QTBUG-51208] Corrected documentation of how non-placeholder
|
||||||
|
characters are handled in format patterns passed to toString().
|
||||||
|
|
||||||
|
- QCoreApplication:
|
||||||
|
* [QTBUG-57171] Fixed an out-of-bounds access if the translatable
|
||||||
|
string passed to tr() ended in '%'.
|
||||||
|
|
||||||
|
- QFileInfo:
|
||||||
|
* [QTBUG-72644] Fixed a bug that would cause QFileInfo to report an
|
||||||
|
link incorrectly as a non-link.
|
||||||
|
|
||||||
|
- QLocale:
|
||||||
|
* Fixed a crash if qDebug() is used after main() has exited.
|
||||||
|
* [QTBUG-73403] Fixed a race condition in getting the system locale
|
||||||
|
(possible regression from Qt 5.11.x)
|
||||||
|
|
||||||
|
- QSysInfo:
|
||||||
|
* Fixed a bug on BSD systems in getting the machineUniqueId().
|
||||||
|
* Fixed a bug on Windows in 32-bit applications getting the
|
||||||
|
machineUniqueId() when the OS is 64-bit.
|
||||||
|
|
||||||
|
- QWaitCondition:
|
||||||
|
* Fixed handling of wait(QDeadlineTimer::Forever) on 32-bit platforms.
|
||||||
|
|
||||||
|
****************************************************************************
|
||||||
|
* QtWidgets *
|
||||||
|
****************************************************************************
|
||||||
|
|
||||||
|
- ItemViews:
|
||||||
|
* Fixed a regression with wrongly drawn centered/right aligned item
|
||||||
|
texts
|
||||||
|
|
||||||
|
****************************************************************************
|
||||||
|
* Third-Party Code *
|
||||||
|
****************************************************************************
|
||||||
|
|
||||||
|
- libpng was updated to version 1.6.36
|
||||||
|
|
||||||
|
****************************************************************************
|
||||||
|
* Freetype *
|
||||||
|
****************************************************************************
|
||||||
|
|
||||||
|
- Upgraded bundled Freetype version to 2.9.1. This also adds support for
|
||||||
|
the latest emoji font in use on Android 9.
|
||||||
|
|
||||||
|
****************************************************************************
|
||||||
|
* Android *
|
||||||
|
****************************************************************************
|
||||||
|
|
||||||
|
- Added the --no-strip command line option to androiddeployqt.
|
||||||
|
|
||||||
|
- qmake:
|
||||||
|
* Can now set the version name and code for Android using
|
||||||
|
ANDROID_VERSION_NAME and ANDROID_VERSION_CODE respectively in the pro
|
||||||
|
file.
|
||||||
|
|
||||||
|
****************************************************************************
|
||||||
|
* Windows *
|
||||||
|
****************************************************************************
|
||||||
|
|
||||||
|
- Fixed an issue where loading fonts from files or data would sometimes
|
||||||
|
mistakenly classify them as oblique.
|
||||||
|
|
||||||
|
****************************************************************************
|
||||||
|
* qmake *
|
||||||
|
****************************************************************************
|
||||||
|
|
||||||
|
- [QTBUG-27079] A new feature "cmdline" was added that implies "CONFIG +=
|
||||||
|
console" and "CONFIG -= app_bundle".
|
@ -59,6 +59,8 @@ int main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
Q_INIT_RESOURCE(systray);
|
Q_INIT_RESOURCE(systray);
|
||||||
|
|
||||||
|
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||||
|
|
||||||
QApplication app(argc, argv);
|
QApplication app(argc, argv);
|
||||||
|
|
||||||
if (!QSystemTrayIcon::isSystemTrayAvailable()) {
|
if (!QSystemTrayIcon::isSystemTrayAvailable()) {
|
||||||
|
@ -59,6 +59,8 @@ int main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
Q_INIT_RESOURCE(classwizard);
|
Q_INIT_RESOURCE(classwizard);
|
||||||
|
|
||||||
|
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||||
|
|
||||||
QApplication app(argc, argv);
|
QApplication app(argc, argv);
|
||||||
|
|
||||||
#ifndef QT_NO_TRANSLATION
|
#ifndef QT_NO_TRANSLATION
|
||||||
|
@ -59,6 +59,8 @@ int main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
Q_INIT_RESOURCE(licensewizard);
|
Q_INIT_RESOURCE(licensewizard);
|
||||||
|
|
||||||
|
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||||
|
|
||||||
QApplication app(argc, argv);
|
QApplication app(argc, argv);
|
||||||
|
|
||||||
#ifndef QT_NO_TRANSLATION
|
#ifndef QT_NO_TRANSLATION
|
||||||
|
@ -59,6 +59,7 @@
|
|||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||||
QApplication app(argc, argv);
|
QApplication app(argc, argv);
|
||||||
QGuiApplication::setApplicationDisplayName(Dialog::tr("Standard Dialogs"));
|
QGuiApplication::setApplicationDisplayName(Dialog::tr("Standard Dialogs"));
|
||||||
|
|
||||||
|
@ -123,6 +123,8 @@ QWizardPage *createConclusionPage()
|
|||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
//! [9] //! [11]
|
//! [9] //! [11]
|
||||||
{
|
{
|
||||||
|
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||||
|
|
||||||
QApplication app(argc, argv);
|
QApplication app(argc, argv);
|
||||||
|
|
||||||
#ifndef QT_NO_TRANSLATION
|
#ifndef QT_NO_TRANSLATION
|
||||||
|
@ -28,6 +28,7 @@ for(resource, RESOURCES) {
|
|||||||
!exists($$absolute_path($$resource, $$_PRO_FILE_PWD_)): \
|
!exists($$absolute_path($$resource, $$_PRO_FILE_PWD_)): \
|
||||||
warning("Failure to find: $$resource")
|
warning("Failure to find: $$resource")
|
||||||
qmake_immediate.files += $$resource
|
qmake_immediate.files += $$resource
|
||||||
|
OTHER_FILES *= $$resource
|
||||||
}
|
}
|
||||||
RESOURCES -= $$resource
|
RESOURCES -= $$resource
|
||||||
next()
|
next()
|
||||||
@ -57,6 +58,7 @@ for(resource, RESOURCES) {
|
|||||||
alias = $$relative_path($$file, $$abs_base)
|
alias = $$relative_path($$file, $$abs_base)
|
||||||
resource_file_content += \
|
resource_file_content += \
|
||||||
"<file alias=\"$$xml_escape($$alias)\">$$xml_escape($$file)</file>"
|
"<file alias=\"$$xml_escape($$alias)\">$$xml_escape($$file)</file>"
|
||||||
|
OTHER_FILES *= $$file
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,9 +75,11 @@ for(resource, RESOURCES) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
!isEmpty(RESOURCES):contains(TEMPLATE, .*lib):plugin:static {
|
!isEmpty(RESOURCES):contains(TEMPLATE, .*lib):plugin:static {
|
||||||
resource_init_function = $$lower($$basename(TARGET))_plugin_resource_init
|
pluginBaseName = $$basename(TARGET)
|
||||||
|
pluginName = $$lower($$replace(pluginBaseName, [-], _))
|
||||||
|
resource_init_function = $${pluginName}_plugin_resource_init
|
||||||
DEFINES += "QT_PLUGIN_RESOURCE_INIT_FUNCTION=$$resource_init_function"
|
DEFINES += "QT_PLUGIN_RESOURCE_INIT_FUNCTION=$$resource_init_function"
|
||||||
RESOURCE_INIT_CPP = $$OUT_PWD/$$lower($$basename(TARGET))_plugin_resources.cpp
|
RESOURCE_INIT_CPP = $$OUT_PWD/$${pluginName}_plugin_resources.cpp
|
||||||
|
|
||||||
GENERATED_SOURCES += $$RESOURCE_INIT_CPP
|
GENERATED_SOURCES += $$RESOURCE_INIT_CPP
|
||||||
QMAKE_DISTCLEAN += $$RESOURCE_INIT_CPP
|
QMAKE_DISTCLEAN += $$RESOURCE_INIT_CPP
|
||||||
|
3
src/3rdparty/angle/src/libANGLE/Context.cpp
vendored
3
src/3rdparty/angle/src/libANGLE/Context.cpp
vendored
@ -451,7 +451,8 @@ egl::Error Context::onDestroy(const egl::Display *display)
|
|||||||
|
|
||||||
for (auto &zeroTexture : mZeroTextures)
|
for (auto &zeroTexture : mZeroTextures)
|
||||||
{
|
{
|
||||||
ANGLE_TRY(zeroTexture.second->onDestroy(this));
|
auto result = zeroTexture.second->onDestroy(this);
|
||||||
|
ANGLE_TRY(egl::Error(result));
|
||||||
zeroTexture.second.set(this, nullptr);
|
zeroTexture.second.set(this, nullptr);
|
||||||
}
|
}
|
||||||
mZeroTextures.clear();
|
mZeroTextures.clear();
|
||||||
|
8
src/3rdparty/angle/src/libANGLE/Stream.cpp
vendored
8
src/3rdparty/angle/src/libANGLE/Stream.cpp
vendored
@ -192,8 +192,9 @@ Error Stream::consumerAcquire(const gl::Context *context)
|
|||||||
{
|
{
|
||||||
if (mPlanes[i].texture != nullptr)
|
if (mPlanes[i].texture != nullptr)
|
||||||
{
|
{
|
||||||
ANGLE_TRY(mPlanes[i].texture->acquireImageFromStream(
|
auto result = mPlanes[i].texture->acquireImageFromStream(
|
||||||
context, mProducerImplementation->getGLFrameDescription(i)));
|
context, mProducerImplementation->getGLFrameDescription(i));
|
||||||
|
ANGLE_TRY(Error(result));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,7 +214,8 @@ Error Stream::consumerRelease(const gl::Context *context)
|
|||||||
{
|
{
|
||||||
if (mPlanes[i].texture != nullptr)
|
if (mPlanes[i].texture != nullptr)
|
||||||
{
|
{
|
||||||
ANGLE_TRY(mPlanes[i].texture->releaseImageFromStream(context));
|
auto result = mPlanes[i].texture->releaseImageFromStream(context);
|
||||||
|
ANGLE_TRY(Error(result));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
3
src/3rdparty/angle/src/libANGLE/Texture.cpp
vendored
3
src/3rdparty/angle/src/libANGLE/Texture.cpp
vendored
@ -550,7 +550,8 @@ Error Texture::onDestroy(const Context *context)
|
|||||||
{
|
{
|
||||||
if (mBoundSurface)
|
if (mBoundSurface)
|
||||||
{
|
{
|
||||||
ANGLE_TRY(mBoundSurface->releaseTexImage(context, EGL_BACK_BUFFER));
|
auto result = mBoundSurface->releaseTexImage(context, EGL_BACK_BUFFER);
|
||||||
|
ANGLE_TRY(Error(result));
|
||||||
mBoundSurface = nullptr;
|
mBoundSurface = nullptr;
|
||||||
}
|
}
|
||||||
if (mBoundStream)
|
if (mBoundStream)
|
||||||
|
@ -376,7 +376,8 @@ egl::Error Renderer9::initializeDevice()
|
|||||||
|
|
||||||
ASSERT(!mBlit);
|
ASSERT(!mBlit);
|
||||||
mBlit = new Blit9(this);
|
mBlit = new Blit9(this);
|
||||||
ANGLE_TRY(mBlit->initialize());
|
auto result = mBlit->initialize();
|
||||||
|
ANGLE_TRY(egl::Error(result));
|
||||||
|
|
||||||
ASSERT(!mVertexDataManager && !mIndexDataManager);
|
ASSERT(!mVertexDataManager && !mIndexDataManager);
|
||||||
mVertexDataManager = new VertexDataManager(this);
|
mVertexDataManager = new VertexDataManager(this);
|
||||||
|
@ -0,0 +1,93 @@
|
|||||||
|
From 2d8118620d4871f74a3ddca233529ff540384477 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yuhang Zhao <2546789017@qq.com>
|
||||||
|
Date: Wed, 13 Feb 2019 23:26:55 +0800
|
||||||
|
Subject: [PATCH] Fix compilation with icc, converting between egl's and gl's
|
||||||
|
Error types
|
||||||
|
|
||||||
|
Each has two constructors from the other, one copying the other
|
||||||
|
moving; and this leads to an ambiguous overload when converting
|
||||||
|
Texture::onDestroy()'s gl::error to the egl::Error that
|
||||||
|
gl::Context::onDestroy() returns. Passing the value through a
|
||||||
|
temporary prevents the move-constructor from being attempted and saves
|
||||||
|
the day. Thanks to Ville Voutilainen for suggesting the fix.
|
||||||
|
|
||||||
|
Fixes: QTBUG-73698
|
||||||
|
Change-Id: I628173399a73cee2e253201bc3e8d3e6477a2fbf
|
||||||
|
---
|
||||||
|
src/3rdparty/angle/src/libANGLE/Context.cpp | 3 ++-
|
||||||
|
src/3rdparty/angle/src/libANGLE/Stream.cpp | 8 +++++---
|
||||||
|
src/3rdparty/angle/src/libANGLE/Texture.cpp | 3 ++-
|
||||||
|
.../angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp | 3 ++-
|
||||||
|
4 files changed, 11 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/3rdparty/angle/src/libANGLE/Context.cpp b/src/3rdparty/angle/src/libANGLE/Context.cpp
|
||||||
|
index f638beda58..84f7936feb 100644
|
||||||
|
--- a/src/3rdparty/angle/src/libANGLE/Context.cpp
|
||||||
|
+++ b/src/3rdparty/angle/src/libANGLE/Context.cpp
|
||||||
|
@@ -451,7 +451,8 @@ egl::Error Context::onDestroy(const egl::Display *display)
|
||||||
|
|
||||||
|
for (auto &zeroTexture : mZeroTextures)
|
||||||
|
{
|
||||||
|
- ANGLE_TRY(zeroTexture.second->onDestroy(this));
|
||||||
|
+ auto result = zeroTexture.second->onDestroy(this);
|
||||||
|
+ ANGLE_TRY(egl::Error(result));
|
||||||
|
zeroTexture.second.set(this, nullptr);
|
||||||
|
}
|
||||||
|
mZeroTextures.clear();
|
||||||
|
diff --git a/src/3rdparty/angle/src/libANGLE/Stream.cpp b/src/3rdparty/angle/src/libANGLE/Stream.cpp
|
||||||
|
index 68279976b7..e384c7d486 100644
|
||||||
|
--- a/src/3rdparty/angle/src/libANGLE/Stream.cpp
|
||||||
|
+++ b/src/3rdparty/angle/src/libANGLE/Stream.cpp
|
||||||
|
@@ -192,8 +192,9 @@ Error Stream::consumerAcquire(const gl::Context *context)
|
||||||
|
{
|
||||||
|
if (mPlanes[i].texture != nullptr)
|
||||||
|
{
|
||||||
|
- ANGLE_TRY(mPlanes[i].texture->acquireImageFromStream(
|
||||||
|
- context, mProducerImplementation->getGLFrameDescription(i)));
|
||||||
|
+ auto result = mPlanes[i].texture->acquireImageFromStream(
|
||||||
|
+ context, mProducerImplementation->getGLFrameDescription(i));
|
||||||
|
+ ANGLE_TRY(Error(result));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -213,7 +214,8 @@ Error Stream::consumerRelease(const gl::Context *context)
|
||||||
|
{
|
||||||
|
if (mPlanes[i].texture != nullptr)
|
||||||
|
{
|
||||||
|
- ANGLE_TRY(mPlanes[i].texture->releaseImageFromStream(context));
|
||||||
|
+ auto result = mPlanes[i].texture->releaseImageFromStream(context);
|
||||||
|
+ ANGLE_TRY(Error(result));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/src/3rdparty/angle/src/libANGLE/Texture.cpp b/src/3rdparty/angle/src/libANGLE/Texture.cpp
|
||||||
|
index da92e65916..7447604fe6 100644
|
||||||
|
--- a/src/3rdparty/angle/src/libANGLE/Texture.cpp
|
||||||
|
+++ b/src/3rdparty/angle/src/libANGLE/Texture.cpp
|
||||||
|
@@ -550,7 +550,8 @@ Error Texture::onDestroy(const Context *context)
|
||||||
|
{
|
||||||
|
if (mBoundSurface)
|
||||||
|
{
|
||||||
|
- ANGLE_TRY(mBoundSurface->releaseTexImage(context, EGL_BACK_BUFFER));
|
||||||
|
+ auto result = mBoundSurface->releaseTexImage(context, EGL_BACK_BUFFER);
|
||||||
|
+ ANGLE_TRY(Error(result));
|
||||||
|
mBoundSurface = nullptr;
|
||||||
|
}
|
||||||
|
if (mBoundStream)
|
||||||
|
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
|
||||||
|
index 75c6298868..b583273641 100644
|
||||||
|
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
|
||||||
|
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
|
||||||
|
@@ -376,7 +376,8 @@ egl::Error Renderer9::initializeDevice()
|
||||||
|
|
||||||
|
ASSERT(!mBlit);
|
||||||
|
mBlit = new Blit9(this);
|
||||||
|
- ANGLE_TRY(mBlit->initialize());
|
||||||
|
+ auto result = mBlit->initialize();
|
||||||
|
+ ANGLE_TRY(egl::Error(result));
|
||||||
|
|
||||||
|
ASSERT(!mVertexDataManager && !mIndexDataManager);
|
||||||
|
mVertexDataManager = new VertexDataManager(this);
|
||||||
|
--
|
||||||
|
2.20.1.windows.1
|
||||||
|
|
@ -908,8 +908,8 @@ QTemporaryFile *QTemporaryFile::createNativeFile(QFile &file)
|
|||||||
qint64 old_off = 0;
|
qint64 old_off = 0;
|
||||||
if(wasOpen)
|
if(wasOpen)
|
||||||
old_off = file.pos();
|
old_off = file.pos();
|
||||||
else
|
else if (!file.open(QIODevice::ReadOnly))
|
||||||
file.open(QIODevice::ReadOnly);
|
return nullptr;
|
||||||
//dump data
|
//dump data
|
||||||
QTemporaryFile *ret = new QTemporaryFile;
|
QTemporaryFile *ret = new QTemporaryFile;
|
||||||
if (ret->open()) {
|
if (ret->open()) {
|
||||||
|
@ -66,6 +66,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <new>
|
||||||
|
|
||||||
#include "qobject_p.h"
|
#include "qobject_p.h"
|
||||||
|
|
||||||
@ -585,7 +586,7 @@ bool QTranslatorPrivate::do_load(const QString &realname, const QString &directo
|
|||||||
#endif // QT_USE_MMAP
|
#endif // QT_USE_MMAP
|
||||||
|
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
d->unmapPointer = new char[d->unmapLength];
|
d->unmapPointer = new (std::nothrow) char[d->unmapLength];
|
||||||
if (d->unmapPointer) {
|
if (d->unmapPointer) {
|
||||||
file.seek(0);
|
file.seek(0);
|
||||||
qint64 readResult = file.read(d->unmapPointer, d->unmapLength);
|
qint64 readResult = file.read(d->unmapPointer, d->unmapLength);
|
||||||
|
@ -124,7 +124,7 @@ QImageData * QImageData::create(const QSize &size, QImage::Format format)
|
|||||||
int height = size.height();
|
int height = size.height();
|
||||||
int depth = qt_depthForFormat(format);
|
int depth = qt_depthForFormat(format);
|
||||||
auto params = calculateImageParameters(width, height, depth);
|
auto params = calculateImageParameters(width, height, depth);
|
||||||
if (params.bytesPerLine < 0)
|
if (!params.isValid())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
QScopedPointer<QImageData> d(new QImageData);
|
QScopedPointer<QImageData> d(new QImageData);
|
||||||
@ -783,7 +783,7 @@ QImageData *QImageData::create(uchar *data, int width, int height, int bpl, QIm
|
|||||||
|
|
||||||
const int depth = qt_depthForFormat(format);
|
const int depth = qt_depthForFormat(format);
|
||||||
auto params = calculateImageParameters(width, height, depth);
|
auto params = calculateImageParameters(width, height, depth);
|
||||||
if (params.totalSize < 0)
|
if (!params.isValid())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
if (bpl > 0) {
|
if (bpl > 0) {
|
||||||
@ -1488,10 +1488,17 @@ qsizetype QImage::sizeInBytes() const
|
|||||||
|
|
||||||
\sa scanLine()
|
\sa scanLine()
|
||||||
*/
|
*/
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
|
||||||
|
qsizetype QImage::bytesPerLine() const
|
||||||
|
{
|
||||||
|
return d ? d->bytes_per_line : 0;
|
||||||
|
}
|
||||||
|
#else
|
||||||
int QImage::bytesPerLine() const
|
int QImage::bytesPerLine() const
|
||||||
{
|
{
|
||||||
return d ? d->bytes_per_line : 0;
|
return d ? d->bytes_per_line : 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -226,7 +226,11 @@ public:
|
|||||||
uchar *scanLine(int);
|
uchar *scanLine(int);
|
||||||
const uchar *scanLine(int) const;
|
const uchar *scanLine(int) const;
|
||||||
const uchar *constScanLine(int) const;
|
const uchar *constScanLine(int) const;
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
|
||||||
|
qsizetype bytesPerLine() const;
|
||||||
|
#else
|
||||||
int bytesPerLine() const;
|
int bytesPerLine() const;
|
||||||
|
#endif
|
||||||
|
|
||||||
bool valid(int x, int y) const;
|
bool valid(int x, int y) const;
|
||||||
bool valid(const QPoint &pt) const;
|
bool valid(const QPoint &pt) const;
|
||||||
|
@ -109,6 +109,7 @@ struct Q_GUI_EXPORT QImageData { // internal image data
|
|||||||
struct ImageSizeParameters {
|
struct ImageSizeParameters {
|
||||||
qsizetype bytesPerLine;
|
qsizetype bytesPerLine;
|
||||||
qsizetype totalSize;
|
qsizetype totalSize;
|
||||||
|
bool isValid() const { return bytesPerLine > 0 && totalSize > 0; }
|
||||||
};
|
};
|
||||||
static ImageSizeParameters calculateImageParameters(qsizetype width, qsizetype height, qsizetype depth);
|
static ImageSizeParameters calculateImageParameters(qsizetype width, qsizetype height, qsizetype depth);
|
||||||
};
|
};
|
||||||
@ -135,6 +136,11 @@ QImageData::calculateImageParameters(qsizetype width, qsizetype height, qsizetyp
|
|||||||
qsizetype dummy;
|
qsizetype dummy;
|
||||||
if (mul_overflow(height, qsizetype(sizeof(uchar *)), &dummy))
|
if (mul_overflow(height, qsizetype(sizeof(uchar *)), &dummy))
|
||||||
return invalid; // why is this here?
|
return invalid; // why is this here?
|
||||||
|
#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
|
||||||
|
// Disallow images where width * depth calculations might overflow
|
||||||
|
if (width > (INT_MAX - 31) / depth)
|
||||||
|
return invalid;
|
||||||
|
#endif
|
||||||
|
|
||||||
return { bytes_per_line, total_size };
|
return { bytes_per_line, total_size };
|
||||||
}
|
}
|
||||||
|
@ -71,12 +71,14 @@ public:
|
|||||||
TextureAccess = 0x04,
|
TextureAccess = 0x04,
|
||||||
HWCompositor = 0x08
|
HWCompositor = 0x08
|
||||||
};
|
};
|
||||||
|
Q_ENUM(AccessType);
|
||||||
Q_DECLARE_FLAGS(AccessTypes, AccessType);
|
Q_DECLARE_FLAGS(AccessTypes, AccessType);
|
||||||
|
|
||||||
enum Origin {
|
enum Origin {
|
||||||
OriginBottomLeft,
|
OriginBottomLeft,
|
||||||
OriginTopLeft
|
OriginTopLeft
|
||||||
};
|
};
|
||||||
|
Q_ENUM(Origin);
|
||||||
|
|
||||||
~QPlatformGraphicsBuffer();
|
~QPlatformGraphicsBuffer();
|
||||||
|
|
||||||
|
@ -463,40 +463,16 @@ QList<int> QPlatformIntegration::possibleKeys(const QKeyEvent *) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Should be called by the implementation whenever a new screen is added.
|
\deprecated Use QWindowSystemInterface::handleScreenAdded instead.
|
||||||
|
|
||||||
The first screen added will be the primary screen, used for default-created
|
|
||||||
windows, GL contexts, and other resources unless otherwise specified.
|
|
||||||
|
|
||||||
This adds the screen to QGuiApplication::screens(), and emits the
|
|
||||||
QGuiApplication::screenAdded() signal.
|
|
||||||
|
|
||||||
The screen should be deleted by calling QPlatformIntegration::destroyScreen().
|
|
||||||
*/
|
*/
|
||||||
void QPlatformIntegration::screenAdded(QPlatformScreen *ps, bool isPrimary)
|
void QPlatformIntegration::screenAdded(QPlatformScreen *ps, bool isPrimary)
|
||||||
{
|
{
|
||||||
QScreen *screen = new QScreen(ps);
|
QWindowSystemInterface::handleScreenAdded(ps, isPrimary);
|
||||||
|
|
||||||
if (isPrimary) {
|
|
||||||
QGuiApplicationPrivate::screen_list.prepend(screen);
|
|
||||||
} else {
|
|
||||||
QGuiApplicationPrivate::screen_list.append(screen);
|
|
||||||
}
|
|
||||||
|
|
||||||
QGuiApplicationPrivate::resetCachedDevicePixelRatio();
|
|
||||||
|
|
||||||
emit qGuiApp->screenAdded(screen);
|
|
||||||
|
|
||||||
if (isPrimary)
|
|
||||||
emit qGuiApp->primaryScreenChanged(screen);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Just removes the screen, call destroyScreen instead.
|
\deprecated Use QWindowSystemInterface::handleScreenRemoved instead.
|
||||||
|
|
||||||
\sa destroyScreen()
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void QPlatformIntegration::removeScreen(QScreen *screen)
|
void QPlatformIntegration::removeScreen(QScreen *screen)
|
||||||
{
|
{
|
||||||
const bool wasPrimary = (!QGuiApplicationPrivate::screen_list.isEmpty() && QGuiApplicationPrivate::screen_list.at(0) == screen);
|
const bool wasPrimary = (!QGuiApplicationPrivate::screen_list.isEmpty() && QGuiApplicationPrivate::screen_list.at(0) == screen);
|
||||||
@ -509,38 +485,19 @@ void QPlatformIntegration::removeScreen(QScreen *screen)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Should be called by the implementation whenever a screen is removed.
|
\deprecated Use QWindowSystemInterface::handleScreenRemoved instead.
|
||||||
|
|
||||||
This removes the screen from QGuiApplication::screens(), and deletes it.
|
|
||||||
|
|
||||||
Failing to call this and manually deleting the QPlatformScreen instead may
|
|
||||||
lead to a crash due to a pure virtual call.
|
|
||||||
*/
|
*/
|
||||||
void QPlatformIntegration::destroyScreen(QPlatformScreen *screen)
|
void QPlatformIntegration::destroyScreen(QPlatformScreen *platformScreen)
|
||||||
{
|
{
|
||||||
QScreen *qScreen = screen->screen();
|
QWindowSystemInterface::handleScreenRemoved(platformScreen);
|
||||||
removeScreen(qScreen);
|
|
||||||
delete qScreen;
|
|
||||||
delete screen;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Should be called whenever the primary screen changes.
|
\deprecated Use QWindowSystemInterface::handlePrimaryScreenChanged instead.
|
||||||
|
*/
|
||||||
When the screen specified as primary changes, this method will notify
|
|
||||||
QGuiApplication and emit the QGuiApplication::primaryScreenChanged signal.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void QPlatformIntegration::setPrimaryScreen(QPlatformScreen *newPrimary)
|
void QPlatformIntegration::setPrimaryScreen(QPlatformScreen *newPrimary)
|
||||||
{
|
{
|
||||||
QScreen* newPrimaryScreen = newPrimary->screen();
|
QWindowSystemInterface::handlePrimaryScreenChanged(newPrimary);
|
||||||
int idx = QGuiApplicationPrivate::screen_list.indexOf(newPrimaryScreen);
|
|
||||||
Q_ASSERT(idx >= 0);
|
|
||||||
if (idx == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
QGuiApplicationPrivate::screen_list.swapItemsAt(0, idx);
|
|
||||||
emit qGuiApp->primaryScreenChanged(newPrimaryScreen);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList QPlatformIntegration::themeNames() const
|
QStringList QPlatformIntegration::themeNames() const
|
||||||
|
@ -192,7 +192,9 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
virtual void setApplicationIcon(const QIcon &icon) const;
|
virtual void setApplicationIcon(const QIcon &icon) const;
|
||||||
|
|
||||||
void removeScreen(QScreen *screen);
|
#if QT_DEPRECATED_SINCE(5, 12)
|
||||||
|
QT_DEPRECATED_X("Use QWindowSystemInterface::handleScreenRemoved") void removeScreen(QScreen *screen);
|
||||||
|
#endif
|
||||||
|
|
||||||
virtual void beep() const;
|
virtual void beep() const;
|
||||||
|
|
||||||
@ -203,9 +205,11 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
QPlatformIntegration() = default;
|
QPlatformIntegration() = default;
|
||||||
|
|
||||||
void screenAdded(QPlatformScreen *screen, bool isPrimary = false);
|
#if QT_DEPRECATED_SINCE(5, 12)
|
||||||
void destroyScreen(QPlatformScreen *screen);
|
QT_DEPRECATED_X("Use QWindowSystemInterface::handleScreenAdded") void screenAdded(QPlatformScreen *screen, bool isPrimary = false);
|
||||||
void setPrimaryScreen(QPlatformScreen *newPrimary);
|
QT_DEPRECATED_X("Use QWindowSystemInterface::handleScreenRemoved") void destroyScreen(QPlatformScreen *screen);
|
||||||
|
QT_DEPRECATED_X("Use QWindowSystemInterface::handlePrimaryScreenChanged") void setPrimaryScreen(QPlatformScreen *newPrimary);
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -61,8 +61,11 @@ QPlatformScreen::~QPlatformScreen()
|
|||||||
{
|
{
|
||||||
Q_D(QPlatformScreen);
|
Q_D(QPlatformScreen);
|
||||||
if (d->screen) {
|
if (d->screen) {
|
||||||
qWarning("Manually deleting a QPlatformScreen. Call QPlatformIntegration::destroyScreen instead.");
|
qWarning("Manually deleting a QPlatformScreen. Call QWindowSystemInterface::handleScreenRemoved instead.");
|
||||||
|
QT_WARNING_PUSH
|
||||||
|
QT_WARNING_DISABLE_DEPRECATED
|
||||||
QGuiApplicationPrivate::platformIntegration()->removeScreen(d->screen);
|
QGuiApplicationPrivate::platformIntegration()->removeScreen(d->screen);
|
||||||
|
QT_WARNING_POP
|
||||||
delete d->screen;
|
delete d->screen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -169,6 +169,7 @@ private:
|
|||||||
friend class QPlatformIntegration;
|
friend class QPlatformIntegration;
|
||||||
friend class QPlatformScreen;
|
friend class QPlatformScreen;
|
||||||
friend class QHighDpiScaling;
|
friend class QHighDpiScaling;
|
||||||
|
friend class QWindowSystemInterface;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef QT_NO_DEBUG_STREAM
|
#ifndef QT_NO_DEBUG_STREAM
|
||||||
|
@ -1922,9 +1922,6 @@ void QWindowPrivate::destroy()
|
|||||||
resizeEventPending = true;
|
resizeEventPending = true;
|
||||||
receivedExpose = false;
|
receivedExpose = false;
|
||||||
exposed = false;
|
exposed = false;
|
||||||
|
|
||||||
if (wasVisible)
|
|
||||||
maybeQuitOnLastWindowClosed();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -2313,8 +2310,17 @@ bool QWindow::event(QEvent *ev)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
case QEvent::Close:
|
case QEvent::Close:
|
||||||
if (ev->isAccepted())
|
if (ev->isAccepted()) {
|
||||||
|
Q_D(QWindow);
|
||||||
|
bool wasVisible = isVisible();
|
||||||
destroy();
|
destroy();
|
||||||
|
if (wasVisible) {
|
||||||
|
// FIXME: This check for visibility is a workaround for both QWidgetWindow
|
||||||
|
// and QWindow having logic to emit lastWindowClosed, and possibly quit the
|
||||||
|
// application. We should find a better way to handle this.
|
||||||
|
d->maybeQuitOnLastWindowClosed();
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QEvent::Expose:
|
case QEvent::Expose:
|
||||||
|
@ -780,6 +780,72 @@ QT_DEFINE_QPA_EVENT_HANDLER(void, handleTouchCancelEvent, QWindow *window, ulong
|
|||||||
QWindowSystemInterfacePrivate::handleWindowSystemEvent<Delivery>(e);
|
QWindowSystemInterfacePrivate::handleWindowSystemEvent<Delivery>(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Should be called by the implementation whenever a new screen is added.
|
||||||
|
|
||||||
|
The first screen added will be the primary screen, used for default-created
|
||||||
|
windows, GL contexts, and other resources unless otherwise specified.
|
||||||
|
|
||||||
|
This adds the screen to QGuiApplication::screens(), and emits the
|
||||||
|
QGuiApplication::screenAdded() signal.
|
||||||
|
|
||||||
|
The screen should be deleted by calling QWindowSystemInterface::handleScreenRemoved().
|
||||||
|
*/
|
||||||
|
void QWindowSystemInterface::handleScreenAdded(QPlatformScreen *ps, bool isPrimary)
|
||||||
|
{
|
||||||
|
QScreen *screen = new QScreen(ps);
|
||||||
|
|
||||||
|
if (isPrimary)
|
||||||
|
QGuiApplicationPrivate::screen_list.prepend(screen);
|
||||||
|
else
|
||||||
|
QGuiApplicationPrivate::screen_list.append(screen);
|
||||||
|
|
||||||
|
QGuiApplicationPrivate::resetCachedDevicePixelRatio();
|
||||||
|
|
||||||
|
emit qGuiApp->screenAdded(screen);
|
||||||
|
|
||||||
|
if (isPrimary)
|
||||||
|
emit qGuiApp->primaryScreenChanged(screen);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Should be called by the implementation whenever a screen is removed.
|
||||||
|
|
||||||
|
This removes the screen from QGuiApplication::screens(), and deletes it.
|
||||||
|
|
||||||
|
Failing to call this and manually deleting the QPlatformScreen instead may
|
||||||
|
lead to a crash due to a pure virtual call.
|
||||||
|
*/
|
||||||
|
void QWindowSystemInterface::handleScreenRemoved(QPlatformScreen *platformScreen)
|
||||||
|
{
|
||||||
|
QT_WARNING_PUSH
|
||||||
|
QT_WARNING_DISABLE_DEPRECATED
|
||||||
|
QGuiApplicationPrivate::platformIntegration()->removeScreen(platformScreen->screen());
|
||||||
|
QT_WARNING_POP
|
||||||
|
|
||||||
|
// Important to keep this order since the QSceen doesn't own the platform screen
|
||||||
|
delete platformScreen->screen();
|
||||||
|
delete platformScreen;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Should be called whenever the primary screen changes.
|
||||||
|
|
||||||
|
When the screen specified as primary changes, this method will notify
|
||||||
|
QGuiApplication and emit the QGuiApplication::primaryScreenChanged signal.
|
||||||
|
*/
|
||||||
|
void QWindowSystemInterface::handlePrimaryScreenChanged(QPlatformScreen *newPrimary)
|
||||||
|
{
|
||||||
|
QScreen *newPrimaryScreen = newPrimary->screen();
|
||||||
|
int indexOfScreen = QGuiApplicationPrivate::screen_list.indexOf(newPrimaryScreen);
|
||||||
|
Q_ASSERT(indexOfScreen >= 0);
|
||||||
|
if (indexOfScreen == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
QGuiApplicationPrivate::screen_list.swapItemsAt(0, indexOfScreen);
|
||||||
|
emit qGuiApp->primaryScreenChanged(newPrimaryScreen);
|
||||||
|
}
|
||||||
|
|
||||||
void QWindowSystemInterface::handleScreenOrientationChange(QScreen *screen, Qt::ScreenOrientation orientation)
|
void QWindowSystemInterface::handleScreenOrientationChange(QScreen *screen, Qt::ScreenOrientation orientation)
|
||||||
{
|
{
|
||||||
QWindowSystemInterfacePrivate::ScreenOrientationEvent *e =
|
QWindowSystemInterfacePrivate::ScreenOrientationEvent *e =
|
||||||
|
@ -233,6 +233,10 @@ public:
|
|||||||
static bool handleNativeEvent(QWindow *window, const QByteArray &eventType, void *message, long *result);
|
static bool handleNativeEvent(QWindow *window, const QByteArray &eventType, void *message, long *result);
|
||||||
|
|
||||||
// Changes to the screen
|
// Changes to the screen
|
||||||
|
static void handleScreenAdded(QPlatformScreen *screen, bool isPrimary = false);
|
||||||
|
static void handleScreenRemoved(QPlatformScreen *screen);
|
||||||
|
static void handlePrimaryScreenChanged(QPlatformScreen *newPrimary);
|
||||||
|
|
||||||
static void handleScreenOrientationChange(QScreen *screen, Qt::ScreenOrientation newOrientation);
|
static void handleScreenOrientationChange(QScreen *screen, Qt::ScreenOrientation newOrientation);
|
||||||
static void handleScreenGeometryChange(QScreen *screen, const QRect &newGeometry, const QRect &newAvailableGeometry);
|
static void handleScreenGeometryChange(QScreen *screen, const QRect &newGeometry, const QRect &newAvailableGeometry);
|
||||||
static void handleScreenLogicalDotsPerInchChange(QScreen *screen, qreal newDpiX, qreal newDpiY);
|
static void handleScreenLogicalDotsPerInchChange(QScreen *screen, qreal newDpiX, qreal newDpiY);
|
||||||
|
@ -58,23 +58,17 @@
|
|||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <qbasictimer.h>
|
#include <qbasictimer.h>
|
||||||
#include "private/qfunctions_p.h"
|
#include "private/qfunctions_p.h"
|
||||||
|
#include <qloggingcategory.h>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
// #define LAYOUT_DEBUG
|
|
||||||
|
|
||||||
#ifdef LAYOUT_DEBUG
|
|
||||||
#define LDEBUG qDebug()
|
|
||||||
#define INC_INDENT debug_indent += " "
|
|
||||||
#define DEC_INDENT debug_indent = debug_indent.left(debug_indent.length()-2)
|
|
||||||
#else
|
|
||||||
#define LDEBUG if(0) qDebug()
|
|
||||||
#define INC_INDENT do {} while(0)
|
|
||||||
#define DEC_INDENT do {} while(0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
Q_LOGGING_CATEGORY(lcDraw, "qt.text.drawing")
|
||||||
|
Q_LOGGING_CATEGORY(lcHit, "qt.text.hittest")
|
||||||
|
Q_LOGGING_CATEGORY(lcLayout, "qt.text.layout")
|
||||||
|
Q_LOGGING_CATEGORY(lcTable, "qt.text.layout.table")
|
||||||
|
|
||||||
// ################ should probably add frameFormatChange notification!
|
// ################ should probably add frameFormatChange notification!
|
||||||
|
|
||||||
struct QTextLayoutStruct;
|
struct QTextLayoutStruct;
|
||||||
@ -583,16 +577,16 @@ QTextDocumentLayoutPrivate::hitTest(QTextFrame *frame, const QFixedPoint &point,
|
|||||||
|
|
||||||
QTextFrame *rootFrame = docPrivate->rootFrame();
|
QTextFrame *rootFrame = docPrivate->rootFrame();
|
||||||
|
|
||||||
// LDEBUG << "checking frame" << frame->firstPosition() << "point=" << point
|
qCDebug(lcHit) << "checking frame" << frame->firstPosition() << "point=" << point.toPointF()
|
||||||
// << "position" << fd->position << "size" << fd->size;
|
<< "position" << fd->position.toPointF() << "size" << fd->size.toSizeF();
|
||||||
if (frame != rootFrame) {
|
if (frame != rootFrame) {
|
||||||
if (relativePoint.y < 0 || relativePoint.x < 0) {
|
if (relativePoint.y < 0 || relativePoint.x < 0) {
|
||||||
*position = frame->firstPosition() - 1;
|
*position = frame->firstPosition() - 1;
|
||||||
// LDEBUG << "before pos=" << *position;
|
qCDebug(lcHit) << "before pos=" << *position;
|
||||||
return PointBefore;
|
return PointBefore;
|
||||||
} else if (relativePoint.y > fd->size.height || relativePoint.x > fd->size.width) {
|
} else if (relativePoint.y > fd->size.height || relativePoint.x > fd->size.width) {
|
||||||
*position = frame->lastPosition() + 1;
|
*position = frame->lastPosition() + 1;
|
||||||
// LDEBUG << "after pos=" << *position;
|
qCDebug(lcHit) << "after pos=" << *position;
|
||||||
return PointAfter;
|
return PointAfter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -666,8 +660,6 @@ QTextDocumentLayoutPrivate::HitPoint
|
|||||||
QTextDocumentLayoutPrivate::hitTest(QTextFrame::Iterator it, HitPoint hit, const QFixedPoint &p,
|
QTextDocumentLayoutPrivate::hitTest(QTextFrame::Iterator it, HitPoint hit, const QFixedPoint &p,
|
||||||
int *position, QTextLayout **l, Qt::HitTestAccuracy accuracy) const
|
int *position, QTextLayout **l, Qt::HitTestAccuracy accuracy) const
|
||||||
{
|
{
|
||||||
INC_INDENT;
|
|
||||||
|
|
||||||
for (; !it.atEnd(); ++it) {
|
for (; !it.atEnd(); ++it) {
|
||||||
QTextFrame *c = it.currentFrame();
|
QTextFrame *c = it.currentFrame();
|
||||||
HitPoint hp;
|
HitPoint hp;
|
||||||
@ -693,8 +685,7 @@ QTextDocumentLayoutPrivate::hitTest(QTextFrame::Iterator it, HitPoint hit, const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DEC_INDENT;
|
qCDebug(lcHit) << "inside=" << hit << " pos=" << *position;
|
||||||
// LDEBUG << "inside=" << hit << " pos=" << *position;
|
|
||||||
return hit;
|
return hit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -741,15 +732,14 @@ QTextDocumentLayoutPrivate::hitTest(const QTextBlock &bl, const QFixedPoint &poi
|
|||||||
QTextLayout *tl = bl.layout();
|
QTextLayout *tl = bl.layout();
|
||||||
QRectF textrect = tl->boundingRect();
|
QRectF textrect = tl->boundingRect();
|
||||||
textrect.translate(tl->position());
|
textrect.translate(tl->position());
|
||||||
// LDEBUG << " checking block" << bl.position() << "point=" << point
|
qCDebug(lcHit) << " checking block" << bl.position() << "point=" << point.toPointF() << " tlrect" << textrect;
|
||||||
// << " tlrect" << textrect;
|
|
||||||
*position = bl.position();
|
*position = bl.position();
|
||||||
if (point.y.toReal() < textrect.top()) {
|
if (point.y.toReal() < textrect.top()) {
|
||||||
// LDEBUG << " before pos=" << *position;
|
qCDebug(lcHit) << " before pos=" << *position;
|
||||||
return PointBefore;
|
return PointBefore;
|
||||||
} else if (point.y.toReal() > textrect.bottom()) {
|
} else if (point.y.toReal() > textrect.bottom()) {
|
||||||
*position += bl.length();
|
*position += bl.length();
|
||||||
// LDEBUG << " after pos=" << *position;
|
qCDebug(lcHit) << " after pos=" << *position;
|
||||||
return PointAfter;
|
return PointAfter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -781,7 +771,7 @@ QTextDocumentLayoutPrivate::hitTest(const QTextBlock &bl, const QFixedPoint &poi
|
|||||||
}
|
}
|
||||||
*position += off;
|
*position += off;
|
||||||
|
|
||||||
// LDEBUG << " inside=" << hit << " pos=" << *position;
|
qCDebug(lcHit) << " inside=" << hit << " pos=" << *position;
|
||||||
return hit;
|
return hit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -944,8 +934,7 @@ void QTextDocumentLayoutPrivate::drawFrame(const QPointF &offset, QPainter *pain
|
|||||||
|| off.x() > context.clip.right() || off.x() + fd->size.width.toReal() < context.clip.left()))
|
|| off.x() > context.clip.right() || off.x() + fd->size.width.toReal() < context.clip.left()))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// LDEBUG << debug_indent << "drawFrame" << frame->firstPosition() << "--" << frame->lastPosition() << "at" << offset;
|
qCDebug(lcDraw) << "drawFrame" << frame->firstPosition() << "--" << frame->lastPosition() << "at" << offset;
|
||||||
// INC_INDENT;
|
|
||||||
|
|
||||||
// if the cursor is /on/ a table border we may need to repaint it
|
// if the cursor is /on/ a table border we may need to repaint it
|
||||||
// afterwards, as we usually draw the decoration first
|
// afterwards, as we usually draw the decoration first
|
||||||
@ -1076,8 +1065,6 @@ void QTextDocumentLayoutPrivate::drawFrame(const QPointF &offset, QPainter *pain
|
|||||||
painter->setPen(oldPen);
|
painter->setPen(oldPen);
|
||||||
}
|
}
|
||||||
|
|
||||||
// DEC_INDENT;
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1280,7 +1267,7 @@ void QTextDocumentLayoutPrivate::drawBlock(const QPointF &offset, QPainter *pain
|
|||||||
r.translate(offset + tl->position());
|
r.translate(offset + tl->position());
|
||||||
if (!bl.isVisible() || (context.clip.isValid() && (r.bottom() < context.clip.y() || r.top() > context.clip.bottom())))
|
if (!bl.isVisible() || (context.clip.isValid() && (r.bottom() < context.clip.y() || r.top() > context.clip.bottom())))
|
||||||
return;
|
return;
|
||||||
// LDEBUG << debug_indent << "drawBlock" << bl.position() << "at" << offset << "br" << tl->boundingRect();
|
qCDebug(lcDraw) << "drawBlock" << bl.position() << "at" << offset << "br" << tl->boundingRect();
|
||||||
|
|
||||||
QTextBlockFormat blockFormat = bl.blockFormat();
|
QTextBlockFormat blockFormat = bl.blockFormat();
|
||||||
|
|
||||||
@ -1512,7 +1499,7 @@ QTextLayoutStruct QTextDocumentLayoutPrivate::layoutCell(QTextTable *t, const QT
|
|||||||
int layoutFrom, int layoutTo, QTextTableData *td,
|
int layoutFrom, int layoutTo, QTextTableData *td,
|
||||||
QFixed absoluteTableY, bool withPageBreaks)
|
QFixed absoluteTableY, bool withPageBreaks)
|
||||||
{
|
{
|
||||||
LDEBUG << "layoutCell";
|
qCDebug(lcTable) << "layoutCell";
|
||||||
QTextLayoutStruct layoutStruct;
|
QTextLayoutStruct layoutStruct;
|
||||||
layoutStruct.frame = t;
|
layoutStruct.frame = t;
|
||||||
layoutStruct.minimumWidth = 0;
|
layoutStruct.minimumWidth = 0;
|
||||||
@ -1587,7 +1574,7 @@ QTextLayoutStruct QTextDocumentLayoutPrivate::layoutCell(QTextTable *t, const QT
|
|||||||
|
|
||||||
QRectF QTextDocumentLayoutPrivate::layoutTable(QTextTable *table, int layoutFrom, int layoutTo, QFixed parentY)
|
QRectF QTextDocumentLayoutPrivate::layoutTable(QTextTable *table, int layoutFrom, int layoutTo, QFixed parentY)
|
||||||
{
|
{
|
||||||
LDEBUG << "layoutTable";
|
qCDebug(lcTable) << "layoutTable from" << layoutFrom << "to" << layoutTo << "parentY" << parentY;
|
||||||
QTextTableData *td = static_cast<QTextTableData *>(data(table));
|
QTextTableData *td = static_cast<QTextTableData *>(data(table));
|
||||||
Q_ASSERT(td->sizeDirty);
|
Q_ASSERT(td->sizeDirty);
|
||||||
const int rows = table->rows();
|
const int rows = table->rows();
|
||||||
@ -1709,6 +1696,7 @@ recalc_minmax_widths:
|
|||||||
if (length.type() == QTextLength::FixedLength) {
|
if (length.type() == QTextLength::FixedLength) {
|
||||||
td->minWidths[i] = td->widths[i] = qMax(scaleToDevice(QFixed::fromReal(length.rawValue())), td->minWidths.at(i));
|
td->minWidths[i] = td->widths[i] = qMax(scaleToDevice(QFixed::fromReal(length.rawValue())), td->minWidths.at(i));
|
||||||
remainingWidth -= td->widths.at(i);
|
remainingWidth -= td->widths.at(i);
|
||||||
|
qCDebug(lcTable) << "column" << i << "has width constraint" << td->minWidths.at(i) << "px, remaining width now" << remainingWidth;
|
||||||
} else if (length.type() == QTextLength::PercentageLength) {
|
} else if (length.type() == QTextLength::PercentageLength) {
|
||||||
totalPercentage += QFixed::fromReal(length.rawValue());
|
totalPercentage += QFixed::fromReal(length.rawValue());
|
||||||
} else if (length.type() == QTextLength::VariableLength) {
|
} else if (length.type() == QTextLength::VariableLength) {
|
||||||
@ -1716,6 +1704,7 @@ recalc_minmax_widths:
|
|||||||
|
|
||||||
td->widths[i] = td->minWidths.at(i);
|
td->widths[i] = td->minWidths.at(i);
|
||||||
remainingWidth -= td->minWidths.at(i);
|
remainingWidth -= td->minWidths.at(i);
|
||||||
|
qCDebug(lcTable) << "column" << i << "has variable width, min" << td->minWidths.at(i) << "remaining width now" << remainingWidth;
|
||||||
}
|
}
|
||||||
totalMinWidth += td->minWidths.at(i);
|
totalMinWidth += td->minWidths.at(i);
|
||||||
}
|
}
|
||||||
@ -1735,6 +1724,8 @@ recalc_minmax_widths:
|
|||||||
} else {
|
} else {
|
||||||
td->widths[i] = td->minWidths.at(i);
|
td->widths[i] = td->minWidths.at(i);
|
||||||
}
|
}
|
||||||
|
qCDebug(lcTable) << "column" << i << "has width constraint" << columnWidthConstraints.at(i).rawValue()
|
||||||
|
<< "%, allocated width" << td->widths[i] << "remaining width now" << remainingWidth;
|
||||||
remainingWidth -= td->widths.at(i);
|
remainingWidth -= td->widths.at(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1978,9 +1969,12 @@ relayout:
|
|||||||
td->minimumWidth += rightMargin - td->border;
|
td->minimumWidth += rightMargin - td->border;
|
||||||
|
|
||||||
td->maximumWidth = td->columnPositions.at(0);
|
td->maximumWidth = td->columnPositions.at(0);
|
||||||
for (int i = 0; i < columns; ++i)
|
for (int i = 0; i < columns; ++i) {
|
||||||
if (td->maxWidths.at(i) != QFIXED_MAX)
|
if (td->maxWidths.at(i) != QFIXED_MAX)
|
||||||
td->maximumWidth += td->maxWidths.at(i) + 2 * td->border + cellSpacing;
|
td->maximumWidth += td->maxWidths.at(i) + 2 * td->border + cellSpacing;
|
||||||
|
qCDebug(lcTable) << "column" << i << "has final width" << td->widths.at(i).toReal()
|
||||||
|
<< "min" << td->minWidths.at(i).toReal() << "max" << td->maxWidths.at(i).toReal();
|
||||||
|
}
|
||||||
td->maximumWidth += rightMargin - td->border;
|
td->maximumWidth += rightMargin - td->border;
|
||||||
|
|
||||||
td->updateTableSize();
|
td->updateTableSize();
|
||||||
@ -2052,9 +2046,8 @@ void QTextDocumentLayoutPrivate::positionFloat(QTextFrame *frame, QTextLine *cur
|
|||||||
|
|
||||||
QRectF QTextDocumentLayoutPrivate::layoutFrame(QTextFrame *f, int layoutFrom, int layoutTo, QFixed parentY)
|
QRectF QTextDocumentLayoutPrivate::layoutFrame(QTextFrame *f, int layoutFrom, int layoutTo, QFixed parentY)
|
||||||
{
|
{
|
||||||
LDEBUG << "layoutFrame (pre)";
|
qCDebug(lcLayout, "layoutFrame (%d--%d), parent=%p", f->firstPosition(), f->lastPosition(), f->parentFrame());
|
||||||
Q_ASSERT(data(f)->sizeDirty);
|
Q_ASSERT(data(f)->sizeDirty);
|
||||||
// qDebug("layouting frame (%d--%d), parent=%p", f->firstPosition(), f->lastPosition(), f->parentFrame());
|
|
||||||
|
|
||||||
QTextFrameFormat fformat = f->frameFormat();
|
QTextFrameFormat fformat = f->frameFormat();
|
||||||
|
|
||||||
@ -2076,9 +2069,8 @@ QRectF QTextDocumentLayoutPrivate::layoutFrame(QTextFrame *f, int layoutFrom, in
|
|||||||
|
|
||||||
QRectF QTextDocumentLayoutPrivate::layoutFrame(QTextFrame *f, int layoutFrom, int layoutTo, QFixed frameWidth, QFixed frameHeight, QFixed parentY)
|
QRectF QTextDocumentLayoutPrivate::layoutFrame(QTextFrame *f, int layoutFrom, int layoutTo, QFixed frameWidth, QFixed frameHeight, QFixed parentY)
|
||||||
{
|
{
|
||||||
LDEBUG << "layoutFrame from=" << layoutFrom << "to=" << layoutTo;
|
qCDebug(lcLayout, "layoutFrame (%d--%d), parent=%p", f->firstPosition(), f->lastPosition(), f->parentFrame());
|
||||||
Q_ASSERT(data(f)->sizeDirty);
|
Q_ASSERT(data(f)->sizeDirty);
|
||||||
// qDebug("layouting frame (%d--%d), parent=%p", f->firstPosition(), f->lastPosition(), f->parentFrame());
|
|
||||||
|
|
||||||
QTextFrameData *fd = data(f);
|
QTextFrameData *fd = data(f);
|
||||||
QFixed newContentsWidth;
|
QFixed newContentsWidth;
|
||||||
@ -2165,8 +2157,8 @@ QRectF QTextDocumentLayoutPrivate::layoutFrame(QTextFrame *f, int layoutFrom, in
|
|||||||
layoutStruct.maximumWidth = QFIXED_MAX;
|
layoutStruct.maximumWidth = QFIXED_MAX;
|
||||||
layoutStruct.fullLayout = fullLayout || (fd->oldContentsWidth != newContentsWidth);
|
layoutStruct.fullLayout = fullLayout || (fd->oldContentsWidth != newContentsWidth);
|
||||||
layoutStruct.updateRect = QRectF(QPointF(0, 0), QSizeF(qreal(INT_MAX), qreal(INT_MAX)));
|
layoutStruct.updateRect = QRectF(QPointF(0, 0), QSizeF(qreal(INT_MAX), qreal(INT_MAX)));
|
||||||
LDEBUG << "layoutStruct: x_left" << layoutStruct.x_left << "x_right" << layoutStruct.x_right
|
qCDebug(lcLayout) << "layoutStruct: x_left" << layoutStruct.x_left << "x_right" << layoutStruct.x_right
|
||||||
<< "fullLayout" << layoutStruct.fullLayout;
|
<< "fullLayout" << layoutStruct.fullLayout;
|
||||||
fd->oldContentsWidth = newContentsWidth;
|
fd->oldContentsWidth = newContentsWidth;
|
||||||
|
|
||||||
layoutStruct.pageHeight = QFixed::fromReal(document->pageSize().height());
|
layoutStruct.pageHeight = QFixed::fromReal(document->pageSize().height());
|
||||||
@ -2220,7 +2212,7 @@ QRectF QTextDocumentLayoutPrivate::layoutFrame(QTextFrame *f, int layoutFrom, in
|
|||||||
void QTextDocumentLayoutPrivate::layoutFlow(QTextFrame::Iterator it, QTextLayoutStruct *layoutStruct,
|
void QTextDocumentLayoutPrivate::layoutFlow(QTextFrame::Iterator it, QTextLayoutStruct *layoutStruct,
|
||||||
int layoutFrom, int layoutTo, QFixed width)
|
int layoutFrom, int layoutTo, QFixed width)
|
||||||
{
|
{
|
||||||
LDEBUG << "layoutFlow from=" << layoutFrom << "to=" << layoutTo;
|
qCDebug(lcLayout) << "layoutFlow from=" << layoutFrom << "to=" << layoutTo;
|
||||||
QTextFrameData *fd = data(layoutStruct->frame);
|
QTextFrameData *fd = data(layoutStruct->frame);
|
||||||
|
|
||||||
fd->currentLayoutStruct = layoutStruct;
|
fd->currentLayoutStruct = layoutStruct;
|
||||||
@ -2578,9 +2570,8 @@ void QTextDocumentLayoutPrivate::layoutBlock(const QTextBlock &bl, int blockPosi
|
|||||||
QTextLayout *tl = bl.layout();
|
QTextLayout *tl = bl.layout();
|
||||||
const int blockLength = bl.length();
|
const int blockLength = bl.length();
|
||||||
|
|
||||||
LDEBUG << "layoutBlock from=" << layoutFrom << "to=" << layoutTo;
|
qCDebug(lcLayout) << "layoutBlock from=" << layoutFrom << "to=" << layoutTo
|
||||||
|
<< "; width" << layoutStruct->x_right - layoutStruct->x_left << "(maxWidth is btw" << tl->maximumWidth() << ')';
|
||||||
// qDebug() << "layoutBlock; width" << layoutStruct->x_right - layoutStruct->x_left << "(maxWidth is btw" << tl->maximumWidth() << ')';
|
|
||||||
|
|
||||||
if (previousBlockFormat) {
|
if (previousBlockFormat) {
|
||||||
qreal margin = qMax(blockFormat.topMargin(), previousBlockFormat->bottomMargin());
|
qreal margin = qMax(blockFormat.topMargin(), previousBlockFormat->bottomMargin());
|
||||||
@ -2612,7 +2603,7 @@ void QTextDocumentLayoutPrivate::layoutBlock(const QTextBlock &bl, int blockPosi
|
|||||||
// force relayout if we cross a page boundary
|
// force relayout if we cross a page boundary
|
||||||
|| (layoutStruct->pageHeight != QFIXED_MAX && layoutStruct->absoluteY() + QFixed::fromReal(tl->boundingRect().height()) > layoutStruct->pageBottom)) {
|
|| (layoutStruct->pageHeight != QFIXED_MAX && layoutStruct->absoluteY() + QFixed::fromReal(tl->boundingRect().height()) > layoutStruct->pageBottom)) {
|
||||||
|
|
||||||
LDEBUG << " do layout";
|
qCDebug(lcLayout) << "do layout";
|
||||||
QTextOption option = docPrivate->defaultTextOption;
|
QTextOption option = docPrivate->defaultTextOption;
|
||||||
option.setTextDirection(dir);
|
option.setTextDirection(dir);
|
||||||
option.setTabs( blockFormat.tabPositions() );
|
option.setTabs( blockFormat.tabPositions() );
|
||||||
@ -2741,7 +2732,7 @@ void QTextDocumentLayoutPrivate::layoutBlock(const QTextBlock &bl, int blockPosi
|
|||||||
const int cnt = tl->lineCount();
|
const int cnt = tl->lineCount();
|
||||||
QFixed bottom;
|
QFixed bottom;
|
||||||
for (int i = 0; i < cnt; ++i) {
|
for (int i = 0; i < cnt; ++i) {
|
||||||
LDEBUG << "going to move text line" << i;
|
qCDebug(lcLayout) << "going to move text line" << i;
|
||||||
QTextLine line = tl->lineAt(i);
|
QTextLine line = tl->lineAt(i);
|
||||||
layoutStruct->contentsWidth
|
layoutStruct->contentsWidth
|
||||||
= qMax(layoutStruct->contentsWidth, QFixed::fromReal(line.x() + tl->lineAt(i).naturalTextWidth()) + totalRightMargin);
|
= qMax(layoutStruct->contentsWidth, QFixed::fromReal(line.x() + tl->lineAt(i).naturalTextWidth()) + totalRightMargin);
|
||||||
|
@ -86,11 +86,11 @@
|
|||||||
"sources": [
|
"sources": [
|
||||||
{ "type": "openssl" },
|
{ "type": "openssl" },
|
||||||
{
|
{
|
||||||
"libs": "-lssleay32 -llibeay32",
|
"libs": "-lssleay32 -llibeay32 -lUser32 -lWs2_32 -lAdvapi32 -lGdi32",
|
||||||
"condition": "config.win32"
|
"condition": "config.win32"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"libs": "-llibssl -llibcrypto",
|
"libs": "-llibssl -llibcrypto -lUser32 -lWs2_32 -lAdvapi32 -lCrypt32",
|
||||||
"condition": "config.msvc"
|
"condition": "config.msvc"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -173,7 +173,7 @@ QAndroidPlatformIntegration::QAndroidPlatformIntegration(const QStringList ¶
|
|||||||
qFatal("Could not bind GL_ES API");
|
qFatal("Could not bind GL_ES API");
|
||||||
|
|
||||||
m_primaryScreen = new QAndroidPlatformScreen();
|
m_primaryScreen = new QAndroidPlatformScreen();
|
||||||
screenAdded(m_primaryScreen);
|
QWindowSystemInterface::handleScreenAdded(m_primaryScreen);
|
||||||
m_primaryScreen->setPhysicalSize(QSize(m_defaultPhysicalSizeWidth, m_defaultPhysicalSizeHeight));
|
m_primaryScreen->setPhysicalSize(QSize(m_defaultPhysicalSizeWidth, m_defaultPhysicalSizeHeight));
|
||||||
m_primaryScreen->setSize(QSize(m_defaultScreenWidth, m_defaultScreenHeight));
|
m_primaryScreen->setSize(QSize(m_defaultScreenWidth, m_defaultScreenHeight));
|
||||||
m_primaryScreen->setAvailableGeometry(QRect(0, 0, m_defaultGeometryWidth, m_defaultGeometryHeight));
|
m_primaryScreen->setAvailableGeometry(QRect(0, 0, m_defaultGeometryWidth, m_defaultGeometryHeight));
|
||||||
|
@ -53,6 +53,7 @@
|
|||||||
#include <QtGui/private/qguiapplication_p.h>
|
#include <QtGui/private/qguiapplication_p.h>
|
||||||
#include <qpa/qplatforminputcontext.h>
|
#include <qpa/qplatforminputcontext.h>
|
||||||
#include <qpa/qplatforminputcontextfactory_p.h>
|
#include <qpa/qplatforminputcontextfactory_p.h>
|
||||||
|
#include <qpa/qwindowsysteminterface.h>
|
||||||
|
|
||||||
#if QT_CONFIG(tslib)
|
#if QT_CONFIG(tslib)
|
||||||
#include <QtInputSupport/private/qtslib_p.h>
|
#include <QtInputSupport/private/qtslib_p.h>
|
||||||
@ -69,13 +70,13 @@ QBsdFbIntegration::QBsdFbIntegration(const QStringList ¶mList)
|
|||||||
|
|
||||||
QBsdFbIntegration::~QBsdFbIntegration()
|
QBsdFbIntegration::~QBsdFbIntegration()
|
||||||
{
|
{
|
||||||
destroyScreen(m_primaryScreen.take());
|
QWindowSystemInterface::handleScreenRemoved(m_primaryScreen.take());
|
||||||
}
|
}
|
||||||
|
|
||||||
void QBsdFbIntegration::initialize()
|
void QBsdFbIntegration::initialize()
|
||||||
{
|
{
|
||||||
if (m_primaryScreen->initialize())
|
if (m_primaryScreen->initialize())
|
||||||
screenAdded(m_primaryScreen.data());
|
QWindowSystemInterface::handleScreenAdded(m_primaryScreen.data());
|
||||||
else
|
else
|
||||||
qWarning("bsdfb: Failed to initialize screen");
|
qWarning("bsdfb: Failed to initialize screen");
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@ SOURCES += main.mm \
|
|||||||
qcocoaintrospection.mm \
|
qcocoaintrospection.mm \
|
||||||
qcocoakeymapper.mm \
|
qcocoakeymapper.mm \
|
||||||
qcocoamimetypes.mm \
|
qcocoamimetypes.mm \
|
||||||
|
qiosurfacegraphicsbuffer.mm \
|
||||||
messages.cpp
|
messages.cpp
|
||||||
|
|
||||||
HEADERS += qcocoaintegration.h \
|
HEADERS += qcocoaintegration.h \
|
||||||
@ -67,6 +68,7 @@ HEADERS += qcocoaintegration.h \
|
|||||||
qcocoaintrospection.h \
|
qcocoaintrospection.h \
|
||||||
qcocoakeymapper.h \
|
qcocoakeymapper.h \
|
||||||
messages.h \
|
messages.h \
|
||||||
|
qiosurfacegraphicsbuffer.h \
|
||||||
qcocoamimetypes.h
|
qcocoamimetypes.h
|
||||||
|
|
||||||
qtConfig(opengl.*) {
|
qtConfig(opengl.*) {
|
||||||
@ -81,7 +83,7 @@ qtConfig(vulkan) {
|
|||||||
|
|
||||||
RESOURCES += qcocoaresources.qrc
|
RESOURCES += qcocoaresources.qrc
|
||||||
|
|
||||||
LIBS += -framework AppKit -framework CoreServices -framework Carbon -framework IOKit -framework QuartzCore -framework CoreVideo -framework Metal -lcups
|
LIBS += -framework AppKit -framework CoreServices -framework Carbon -framework IOKit -framework QuartzCore -framework CoreVideo -framework Metal -framework IOSurface -lcups
|
||||||
|
|
||||||
QT += \
|
QT += \
|
||||||
core-private gui-private \
|
core-private gui-private \
|
||||||
|
@ -44,13 +44,16 @@
|
|||||||
|
|
||||||
#include <private/qcore_mac_p.h>
|
#include <private/qcore_mac_p.h>
|
||||||
|
|
||||||
|
#include <QScopedPointer>
|
||||||
|
#include "qiosurfacegraphicsbuffer.h"
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class QCocoaBackingStore : public QRasterBackingStore
|
class QNSWindowBackingStore : public QRasterBackingStore
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QCocoaBackingStore(QWindow *window);
|
QNSWindowBackingStore(QWindow *window);
|
||||||
~QCocoaBackingStore();
|
~QNSWindowBackingStore();
|
||||||
|
|
||||||
void flush(QWindow *, const QRegion &, const QPoint &) override;
|
void flush(QWindow *, const QRegion &, const QPoint &) override;
|
||||||
|
|
||||||
@ -60,6 +63,49 @@ private:
|
|||||||
void redrawRoundedBottomCorners(CGRect) const;
|
void redrawRoundedBottomCorners(CGRect) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class QCALayerBackingStore : public QPlatformBackingStore
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QCALayerBackingStore(QWindow *window);
|
||||||
|
~QCALayerBackingStore();
|
||||||
|
|
||||||
|
void resize(const QSize &size, const QRegion &staticContents) override;
|
||||||
|
|
||||||
|
void beginPaint(const QRegion ®ion) override;
|
||||||
|
QPaintDevice *paintDevice() override;
|
||||||
|
void endPaint() override;
|
||||||
|
|
||||||
|
void flush(QWindow *, const QRegion &, const QPoint &) override;
|
||||||
|
void composeAndFlush(QWindow *window, const QRegion ®ion, const QPoint &offset,
|
||||||
|
QPlatformTextureList *textures, bool translucentBackground) override;
|
||||||
|
|
||||||
|
QPlatformGraphicsBuffer *graphicsBuffer() const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QSize m_requestedSize;
|
||||||
|
QRegion m_paintedRegion;
|
||||||
|
|
||||||
|
class GraphicsBuffer : public QIOSurfaceGraphicsBuffer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GraphicsBuffer(const QSize &size, qreal devicePixelRatio,
|
||||||
|
const QPixelFormat &format, QCFType<CGColorSpaceRef> colorSpace);
|
||||||
|
|
||||||
|
QRegion dirtyRegion; // In unscaled coordinates
|
||||||
|
QImage *asImage();
|
||||||
|
|
||||||
|
private:
|
||||||
|
qreal m_devicePixelRatio;
|
||||||
|
QImage m_image;
|
||||||
|
};
|
||||||
|
|
||||||
|
void ensureBackBuffer();
|
||||||
|
bool recreateBackBufferIfNeeded();
|
||||||
|
bool prepareForFlush();
|
||||||
|
|
||||||
|
std::list<std::unique_ptr<GraphicsBuffer>> m_buffers;
|
||||||
|
};
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -42,24 +42,28 @@
|
|||||||
#include "qcocoawindow.h"
|
#include "qcocoawindow.h"
|
||||||
#include "qcocoahelpers.h"
|
#include "qcocoahelpers.h"
|
||||||
|
|
||||||
|
#include <QtCore/qmath.h>
|
||||||
|
|
||||||
|
#include <QuartzCore/CATransaction.h>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
QCocoaBackingStore::QCocoaBackingStore(QWindow *window)
|
QNSWindowBackingStore::QNSWindowBackingStore(QWindow *window)
|
||||||
: QRasterBackingStore(window)
|
: QRasterBackingStore(window)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
QCocoaBackingStore::~QCocoaBackingStore()
|
QNSWindowBackingStore::~QNSWindowBackingStore()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QCocoaBackingStore::windowHasUnifiedToolbar() const
|
bool QNSWindowBackingStore::windowHasUnifiedToolbar() const
|
||||||
{
|
{
|
||||||
Q_ASSERT(window()->handle());
|
Q_ASSERT(window()->handle());
|
||||||
return static_cast<QCocoaWindow *>(window()->handle())->m_drawContentBorderGradient;
|
return static_cast<QCocoaWindow *>(window()->handle())->m_drawContentBorderGradient;
|
||||||
}
|
}
|
||||||
|
|
||||||
QImage::Format QCocoaBackingStore::format() const
|
QImage::Format QNSWindowBackingStore::format() const
|
||||||
{
|
{
|
||||||
if (windowHasUnifiedToolbar())
|
if (windowHasUnifiedToolbar())
|
||||||
return QImage::Format_ARGB32_Premultiplied;
|
return QImage::Format_ARGB32_Premultiplied;
|
||||||
@ -78,7 +82,7 @@ QImage::Format QCocoaBackingStore::format() const
|
|||||||
coordinates, and the \a offset will be the child window's offset in relation
|
coordinates, and the \a offset will be the child window's offset in relation
|
||||||
to the backingstore's top level window.
|
to the backingstore's top level window.
|
||||||
*/
|
*/
|
||||||
void QCocoaBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoint &offset)
|
void QNSWindowBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoint &offset)
|
||||||
{
|
{
|
||||||
if (m_image.isNull())
|
if (m_image.isNull())
|
||||||
return;
|
return;
|
||||||
@ -103,131 +107,113 @@ void QCocoaBackingStore::flush(QWindow *window, const QRegion ®ion, const QPo
|
|||||||
qCDebug(lcQpaBackingStore) << "Flushing" << region << "of" << view << qPrintable(targetViewDescription);
|
qCDebug(lcQpaBackingStore) << "Flushing" << region << "of" << view << qPrintable(targetViewDescription);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Normally a NSView is drawn via drawRect, as part of the display cycle in the
|
||||||
|
// main runloop, via setNeedsDisplay and friends. AppKit will lock focus on each
|
||||||
|
// individual view, starting with the top level and then traversing any subviews,
|
||||||
|
// calling drawRect for each of them. This pull model results in expose events
|
||||||
|
// sent to Qt, which result in drawing to the backingstore and flushing it.
|
||||||
|
// Qt may also decide to paint and flush the backingstore via e.g. timers,
|
||||||
|
// or other events such as mouse events, in which case we're in a push model.
|
||||||
|
// If there is no focused view, it means we're in the latter case, and need
|
||||||
|
// to manually flush the NSWindow after drawing to its graphic context.
|
||||||
|
const bool drawingOutsideOfDisplayCycle = ![NSView focusView];
|
||||||
|
|
||||||
|
// We also need to ensure the flushed view has focus, so that the graphics
|
||||||
|
// context is set up correctly (coordinate system, clipping, etc). Outside
|
||||||
|
// of the normal display cycle there is no focused view, as explained above,
|
||||||
|
// so we have to handle it manually. There's also a corner case inside the
|
||||||
|
// normal display cycle due to way QWidgetBackingStore composits native child
|
||||||
|
// widgets, where we'll get a flush of a native child during the drawRect of
|
||||||
|
// its parent/ancestor, and the parent/ancestor being the one locked by AppKit.
|
||||||
|
// In this case we also need to lock and unlock focus manually.
|
||||||
|
const bool shouldHandleViewLockManually = [NSView focusView] != view;
|
||||||
|
if (shouldHandleViewLockManually && ![view lockFocusIfCanDraw]) {
|
||||||
|
qWarning() << "failed to lock focus of" << view;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const qreal devicePixelRatio = m_image.devicePixelRatio();
|
||||||
|
|
||||||
|
// If the flushed window is a content view, and we're filling the drawn area
|
||||||
|
// completely, or it doesn't have a window background we need to preserve,
|
||||||
|
// we can get away with copying instead of blending the backing store.
|
||||||
|
QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window->handle());
|
||||||
|
const NSCompositingOperation compositingOperation = cocoaWindow->isContentView()
|
||||||
|
&& (cocoaWindow->isOpaque() || view.window.backgroundColor == NSColor.clearColor)
|
||||||
|
? NSCompositingOperationCopy : NSCompositingOperationSourceOver;
|
||||||
|
|
||||||
|
#ifdef QT_DEBUG
|
||||||
|
static bool debugBackingStoreFlush = [[NSUserDefaults standardUserDefaults]
|
||||||
|
boolForKey:@"QtCocoaDebugBackingStoreFlush"];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// The current contexts is typically a NSWindowGraphicsContext, but can be
|
||||||
|
// NSBitmapGraphicsContext e.g. when debugging the view hierarchy in Xcode.
|
||||||
|
// If we need to distinguish things here in the future, we can use e.g.
|
||||||
|
// [NSGraphicsContext drawingToScreen], or the attributes of the context.
|
||||||
|
NSGraphicsContext *graphicsContext = [NSGraphicsContext currentContext];
|
||||||
|
Q_ASSERT_X(graphicsContext, "QCocoaBackingStore",
|
||||||
|
"Focusing the view should give us a current graphics context");
|
||||||
|
|
||||||
// Prevent potentially costly color conversion by assigning the display color space
|
// Prevent potentially costly color conversion by assigning the display color space
|
||||||
// to the backingstore image. This does not copy the underlying image data.
|
// to the backingstore image. This does not copy the underlying image data.
|
||||||
CGColorSpaceRef displayColorSpace = view.window.screen.colorSpace.CGColorSpace;
|
CGColorSpaceRef displayColorSpace = view.window.screen.colorSpace.CGColorSpace;
|
||||||
QCFType<CGImageRef> cgImage = CGImageCreateCopyWithColorSpace(
|
QCFType<CGImageRef> cgImage = CGImageCreateCopyWithColorSpace(
|
||||||
QCFType<CGImageRef>(m_image.toCGImage()), displayColorSpace);
|
QCFType<CGImageRef>(m_image.toCGImage()), displayColorSpace);
|
||||||
|
|
||||||
if (view.layer) {
|
// Create temporary image to use for blitting, without copying image data
|
||||||
// In layer-backed mode, locking focus on a view does not give the right
|
NSImage *backingStoreImage = [[[NSImage alloc] initWithCGImage:cgImage size:NSZeroSize] autorelease];
|
||||||
// view transformation, and doesn't give us a graphics context to render
|
|
||||||
// via when drawing outside of the display cycle. Instead we tell AppKit
|
|
||||||
// that we want to update the layer's content, via [NSView wantsUpdateLayer],
|
|
||||||
// which result in AppKit not creating a backingstore for each layer, and
|
|
||||||
// we then directly set the layer's backingstore (content) to our backingstore,
|
|
||||||
// masked to the part of the subview that is relevant.
|
|
||||||
// FIXME: Figure out if there's a way to do partial updates
|
|
||||||
view.layer.contents = (__bridge id)static_cast<CGImageRef>(cgImage);
|
|
||||||
if (view != topLevelView) {
|
|
||||||
const CGSize topLevelSize = topLevelView.bounds.size;
|
|
||||||
view.layer.contentsRect = CGRectApplyAffineTransform(
|
|
||||||
[view convertRect:view.bounds toView:topLevelView],
|
|
||||||
// The contentsRect is in unit coordinate system
|
|
||||||
CGAffineTransformMakeScale(1.0 / topLevelSize.width, 1.0 / topLevelSize.height));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Normally a NSView is drawn via drawRect, as part of the display cycle in the
|
|
||||||
// main runloop, via setNeedsDisplay and friends. AppKit will lock focus on each
|
|
||||||
// individual view, starting with the top level and then traversing any subviews,
|
|
||||||
// calling drawRect for each of them. This pull model results in expose events
|
|
||||||
// sent to Qt, which result in drawing to the backingstore and flushing it.
|
|
||||||
// Qt may also decide to paint and flush the backingstore via e.g. timers,
|
|
||||||
// or other events such as mouse events, in which case we're in a push model.
|
|
||||||
// If there is no focused view, it means we're in the latter case, and need
|
|
||||||
// to manually flush the NSWindow after drawing to its graphic context.
|
|
||||||
const bool drawingOutsideOfDisplayCycle = ![NSView focusView];
|
|
||||||
|
|
||||||
// We also need to ensure the flushed view has focus, so that the graphics
|
QRegion clippedRegion = region;
|
||||||
// context is set up correctly (coordinate system, clipping, etc). Outside
|
for (QWindow *w = window; w; w = w->parent()) {
|
||||||
// of the normal display cycle there is no focused view, as explained above,
|
if (!w->mask().isEmpty()) {
|
||||||
// so we have to handle it manually. There's also a corner case inside the
|
clippedRegion &= w == window ? w->mask()
|
||||||
// normal display cycle due to way QWidgetBackingStore composits native child
|
: w->mask().translated(window->mapFromGlobal(w->mapToGlobal(QPoint(0, 0))));
|
||||||
// widgets, where we'll get a flush of a native child during the drawRect of
|
|
||||||
// its parent/ancestor, and the parent/ancestor being the one locked by AppKit.
|
|
||||||
// In this case we also need to lock and unlock focus manually.
|
|
||||||
const bool shouldHandleViewLockManually = [NSView focusView] != view;
|
|
||||||
if (shouldHandleViewLockManually && ![view lockFocusIfCanDraw]) {
|
|
||||||
qWarning() << "failed to lock focus of" << view;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const qreal devicePixelRatio = m_image.devicePixelRatio();
|
|
||||||
|
|
||||||
// If the flushed window is a content view, and we're filling the drawn area
|
|
||||||
// completely, or it doesn't have a window background we need to preserve,
|
|
||||||
// we can get away with copying instead of blending the backing store.
|
|
||||||
QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window->handle());
|
|
||||||
const NSCompositingOperation compositingOperation = cocoaWindow->isContentView()
|
|
||||||
&& (cocoaWindow->isOpaque() || view.window.backgroundColor == NSColor.clearColor)
|
|
||||||
? NSCompositingOperationCopy : NSCompositingOperationSourceOver;
|
|
||||||
|
|
||||||
#ifdef QT_DEBUG
|
|
||||||
static bool debugBackingStoreFlush = [[NSUserDefaults standardUserDefaults]
|
|
||||||
boolForKey:@"QtCocoaDebugBackingStoreFlush"];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// The current contexts is typically a NSWindowGraphicsContext, but can be
|
|
||||||
// NSBitmapGraphicsContext e.g. when debugging the view hierarchy in Xcode.
|
|
||||||
// If we need to distinguish things here in the future, we can use e.g.
|
|
||||||
// [NSGraphicsContext drawingToScreen], or the attributes of the context.
|
|
||||||
NSGraphicsContext *graphicsContext = [NSGraphicsContext currentContext];
|
|
||||||
Q_ASSERT_X(graphicsContext, "QCocoaBackingStore",
|
|
||||||
"Focusing the view should give us a current graphics context");
|
|
||||||
|
|
||||||
// Create temporary image to use for blitting, without copying image data
|
|
||||||
NSImage *backingStoreImage = [[[NSImage alloc] initWithCGImage:cgImage size:NSZeroSize] autorelease];
|
|
||||||
|
|
||||||
QRegion clippedRegion = region;
|
|
||||||
for (QWindow *w = window; w; w = w->parent()) {
|
|
||||||
if (!w->mask().isEmpty()) {
|
|
||||||
clippedRegion &= w == window ? w->mask()
|
|
||||||
: w->mask().translated(window->mapFromGlobal(w->mapToGlobal(QPoint(0, 0))));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const QRect &viewLocalRect : clippedRegion) {
|
|
||||||
QPoint backingStoreOffset = viewLocalRect.topLeft() + offset;
|
|
||||||
QRect backingStoreRect(backingStoreOffset * devicePixelRatio, viewLocalRect.size() * devicePixelRatio);
|
|
||||||
if (graphicsContext.flipped) // Flip backingStoreRect to match graphics context
|
|
||||||
backingStoreRect.moveTop(m_image.height() - (backingStoreRect.y() + backingStoreRect.height()));
|
|
||||||
|
|
||||||
CGRect viewRect = viewLocalRect.toCGRect();
|
|
||||||
|
|
||||||
if (windowHasUnifiedToolbar())
|
|
||||||
NSDrawWindowBackground(viewRect);
|
|
||||||
|
|
||||||
[backingStoreImage drawInRect:viewRect fromRect:backingStoreRect.toCGRect()
|
|
||||||
operation:compositingOperation fraction:1.0 respectFlipped:YES hints:nil];
|
|
||||||
|
|
||||||
#ifdef QT_DEBUG
|
|
||||||
if (Q_UNLIKELY(debugBackingStoreFlush)) {
|
|
||||||
[[NSColor colorWithCalibratedRed:drand48() green:drand48() blue:drand48() alpha:0.3] set];
|
|
||||||
[NSBezierPath fillRect:viewRect];
|
|
||||||
|
|
||||||
if (drawingOutsideOfDisplayCycle) {
|
|
||||||
[[[NSColor magentaColor] colorWithAlphaComponent:0.5] set];
|
|
||||||
[NSBezierPath strokeLineFromPoint:viewLocalRect.topLeft().toCGPoint()
|
|
||||||
toPoint:viewLocalRect.bottomRight().toCGPoint()];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
|
|
||||||
if (shouldHandleViewLockManually)
|
|
||||||
[view unlockFocus];
|
|
||||||
|
|
||||||
if (drawingOutsideOfDisplayCycle) {
|
|
||||||
redrawRoundedBottomCorners([view convertRect:region.boundingRect().toCGRect() toView:nil]);
|
|
||||||
[view.window flushWindow];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Done flushing to either CALayer or NSWindow backingstore
|
for (const QRect &viewLocalRect : clippedRegion) {
|
||||||
|
QPoint backingStoreOffset = viewLocalRect.topLeft() + offset;
|
||||||
|
QRect backingStoreRect(backingStoreOffset * devicePixelRatio, viewLocalRect.size() * devicePixelRatio);
|
||||||
|
if (graphicsContext.flipped) // Flip backingStoreRect to match graphics context
|
||||||
|
backingStoreRect.moveTop(m_image.height() - (backingStoreRect.y() + backingStoreRect.height()));
|
||||||
|
|
||||||
|
CGRect viewRect = viewLocalRect.toCGRect();
|
||||||
|
|
||||||
|
if (windowHasUnifiedToolbar())
|
||||||
|
NSDrawWindowBackground(viewRect);
|
||||||
|
|
||||||
|
[backingStoreImage drawInRect:viewRect fromRect:backingStoreRect.toCGRect()
|
||||||
|
operation:compositingOperation fraction:1.0 respectFlipped:YES hints:nil];
|
||||||
|
|
||||||
|
#ifdef QT_DEBUG
|
||||||
|
if (Q_UNLIKELY(debugBackingStoreFlush)) {
|
||||||
|
[[NSColor colorWithCalibratedRed:drand48() green:drand48() blue:drand48() alpha:0.3] set];
|
||||||
|
[NSBezierPath fillRect:viewRect];
|
||||||
|
|
||||||
|
if (drawingOutsideOfDisplayCycle) {
|
||||||
|
[[[NSColor magentaColor] colorWithAlphaComponent:0.5] set];
|
||||||
|
[NSBezierPath strokeLineFromPoint:viewLocalRect.topLeft().toCGPoint()
|
||||||
|
toPoint:viewLocalRect.bottomRight().toCGPoint()];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
|
||||||
|
if (shouldHandleViewLockManually)
|
||||||
|
[view unlockFocus];
|
||||||
|
|
||||||
|
if (drawingOutsideOfDisplayCycle) {
|
||||||
|
redrawRoundedBottomCorners([view convertRect:region.boundingRect().toCGRect() toView:nil]);
|
||||||
|
[view.window flushWindow];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Done flushing to NSWindow backingstore
|
||||||
|
|
||||||
QCocoaWindow *topLevelCocoaWindow = static_cast<QCocoaWindow *>(topLevelWindow->handle());
|
QCocoaWindow *topLevelCocoaWindow = static_cast<QCocoaWindow *>(topLevelWindow->handle());
|
||||||
if (Q_UNLIKELY(topLevelCocoaWindow->m_needsInvalidateShadow)) {
|
if (Q_UNLIKELY(topLevelCocoaWindow->m_needsInvalidateShadow)) {
|
||||||
@ -251,7 +237,7 @@ void QCocoaBackingStore::flush(QWindow *window, const QRegion ®ion, const QPo
|
|||||||
|
|
||||||
https://trac.webkit.org/changeset/85376/webkit
|
https://trac.webkit.org/changeset/85376/webkit
|
||||||
*/
|
*/
|
||||||
void QCocoaBackingStore::redrawRoundedBottomCorners(CGRect windowRect) const
|
void QNSWindowBackingStore::redrawRoundedBottomCorners(CGRect windowRect) const
|
||||||
{
|
{
|
||||||
#if !defined(QT_APPLE_NO_PRIVATE_APIS)
|
#if !defined(QT_APPLE_NO_PRIVATE_APIS)
|
||||||
Q_ASSERT(this->window()->handle());
|
Q_ASSERT(this->window()->handle());
|
||||||
@ -285,4 +271,345 @@ void QCocoaBackingStore::redrawRoundedBottomCorners(CGRect windowRect) const
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// https://stackoverflow.com/a/52722575/2761869
|
||||||
|
template<class R>
|
||||||
|
struct backwards_t {
|
||||||
|
R r;
|
||||||
|
constexpr auto begin() const { using std::rbegin; return rbegin(r); }
|
||||||
|
constexpr auto begin() { using std::rbegin; return rbegin(r); }
|
||||||
|
constexpr auto end() const { using std::rend; return rend(r); }
|
||||||
|
constexpr auto end() { using std::rend; return rend(r); }
|
||||||
|
};
|
||||||
|
template<class R>
|
||||||
|
constexpr backwards_t<R> backwards(R&& r) { return {std::forward<R>(r)}; }
|
||||||
|
|
||||||
|
QCALayerBackingStore::QCALayerBackingStore(QWindow *window)
|
||||||
|
: QPlatformBackingStore(window)
|
||||||
|
{
|
||||||
|
qCDebug(lcQpaBackingStore) << "Creating QCALayerBackingStore for" << window;
|
||||||
|
m_buffers.resize(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
QCALayerBackingStore::~QCALayerBackingStore()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void QCALayerBackingStore::resize(const QSize &size, const QRegion &staticContents)
|
||||||
|
{
|
||||||
|
qCDebug(lcQpaBackingStore) << "Resize requested to" << size;
|
||||||
|
|
||||||
|
if (!staticContents.isNull())
|
||||||
|
qCWarning(lcQpaBackingStore) << "QCALayerBackingStore does not support static contents";
|
||||||
|
|
||||||
|
m_requestedSize = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QCALayerBackingStore::beginPaint(const QRegion ®ion)
|
||||||
|
{
|
||||||
|
Q_UNUSED(region);
|
||||||
|
|
||||||
|
QMacAutoReleasePool pool;
|
||||||
|
|
||||||
|
qCInfo(lcQpaBackingStore) << "Beginning paint of" << region << "into backingstore of" << m_requestedSize;
|
||||||
|
|
||||||
|
ensureBackBuffer(); // Find an unused back buffer, or reserve space for a new one
|
||||||
|
|
||||||
|
const bool bufferWasRecreated = recreateBackBufferIfNeeded();
|
||||||
|
|
||||||
|
m_buffers.back()->lock(QPlatformGraphicsBuffer::SWWriteAccess);
|
||||||
|
|
||||||
|
// Although undocumented, QBackingStore::beginPaint expects the painted region
|
||||||
|
// to be cleared before use if the window has a surface format with an alpha.
|
||||||
|
// Fresh IOSurfaces are already cleared, so we don't need to clear those.
|
||||||
|
if (!bufferWasRecreated && window()->format().hasAlpha()) {
|
||||||
|
qCDebug(lcQpaBackingStore) << "Clearing" << region << "before use";
|
||||||
|
QPainter painter(m_buffers.back()->asImage());
|
||||||
|
painter.setCompositionMode(QPainter::CompositionMode_Source);
|
||||||
|
for (const QRect &rect : region)
|
||||||
|
painter.fillRect(rect, Qt::transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_paintedRegion += region;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QCALayerBackingStore::ensureBackBuffer()
|
||||||
|
{
|
||||||
|
if (window()->format().swapBehavior() == QSurfaceFormat::SingleBuffer)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// The current back buffer may have been assigned to a layer in a previous flush,
|
||||||
|
// but we deferred the swap. Do it now if the surface has been picked up by CA.
|
||||||
|
if (m_buffers.back() && m_buffers.back()->isInUse() && m_buffers.back() != m_buffers.front()) {
|
||||||
|
qCInfo(lcQpaBackingStore) << "Back buffer has been picked up by CA, swapping to front";
|
||||||
|
std::swap(m_buffers.back(), m_buffers.front());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Q_UNLIKELY(lcQpaBackingStore().isDebugEnabled())) {
|
||||||
|
// ┌───────┬───────┬───────┬─────┬──────┐
|
||||||
|
// │ front ┊ spare ┊ spare ┊ ... ┊ back │
|
||||||
|
// └───────┴───────┴───────┴─────┴──────┘
|
||||||
|
for (const auto &buffer : m_buffers) {
|
||||||
|
qCDebug(lcQpaBackingStore).nospace() << " "
|
||||||
|
<< (buffer == m_buffers.front() ? "front" :
|
||||||
|
buffer == m_buffers.back() ? " back" :
|
||||||
|
"spare"
|
||||||
|
) << ": " << buffer.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure our back buffer is ready to draw into. If not, find a buffer that
|
||||||
|
// is not in use, or reserve space for a new buffer if none can be found.
|
||||||
|
for (auto &buffer : backwards(m_buffers)) {
|
||||||
|
if (!buffer || !buffer->isInUse()) {
|
||||||
|
// Buffer is okey to use, swap if necessary
|
||||||
|
if (buffer != m_buffers.back())
|
||||||
|
std::swap(buffer, m_buffers.back());
|
||||||
|
qCDebug(lcQpaBackingStore) << "Using back buffer" << m_buffers.back().get();
|
||||||
|
|
||||||
|
static const int kMaxSwapChainDepth = 3;
|
||||||
|
if (m_buffers.size() > kMaxSwapChainDepth) {
|
||||||
|
qCDebug(lcQpaBackingStore) << "Reducing swap chain depth to" << kMaxSwapChainDepth;
|
||||||
|
m_buffers.erase(std::next(m_buffers.begin(), 1), std::prev(m_buffers.end(), 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
} else if (buffer == m_buffers.front()) {
|
||||||
|
// We've exhausted the available buffers, make room for a new one
|
||||||
|
const int swapChainDepth = m_buffers.size() + 1;
|
||||||
|
qCDebug(lcQpaBackingStore) << "Available buffers exhausted, increasing swap chain depth to" << swapChainDepth;
|
||||||
|
m_buffers.resize(swapChainDepth);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_ASSERT(!m_buffers.back() || !m_buffers.back()->isInUse());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disabled until performance issue on 5K iMac Pro has been investigated further,
|
||||||
|
// as rounding up during resize will typically result in full screen buffer sizes
|
||||||
|
// and low frame rate also for smaller window sizes.
|
||||||
|
#define USE_LAZY_BUFFER_ALLOCATION_DURING_LIVE_WINDOW_RESIZE 0
|
||||||
|
|
||||||
|
bool QCALayerBackingStore::recreateBackBufferIfNeeded()
|
||||||
|
{
|
||||||
|
const qreal devicePixelRatio = window()->devicePixelRatio();
|
||||||
|
QSize requestedBufferSize = m_requestedSize * devicePixelRatio;
|
||||||
|
|
||||||
|
const NSView *backingStoreView = static_cast<QCocoaWindow *>(window()->handle())->view();
|
||||||
|
Q_UNUSED(backingStoreView);
|
||||||
|
|
||||||
|
auto bufferSizeMismatch = [&](const QSize requested, const QSize actual) {
|
||||||
|
#if USE_LAZY_BUFFER_ALLOCATION_DURING_LIVE_WINDOW_RESIZE
|
||||||
|
if (backingStoreView.inLiveResize) {
|
||||||
|
// Prevent over-eager buffer allocation during window resize by reusing larger buffers
|
||||||
|
return requested.width() > actual.width() || requested.height() > actual.height();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return requested != actual;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!m_buffers.back() || bufferSizeMismatch(requestedBufferSize, m_buffers.back()->size())) {
|
||||||
|
#if USE_LAZY_BUFFER_ALLOCATION_DURING_LIVE_WINDOW_RESIZE
|
||||||
|
if (backingStoreView.inLiveResize) {
|
||||||
|
// Prevent over-eager buffer allocation during window resize by rounding up
|
||||||
|
QSize nativeScreenSize = window()->screen()->geometry().size() * devicePixelRatio;
|
||||||
|
requestedBufferSize = QSize(qNextPowerOfTwo(requestedBufferSize.width()),
|
||||||
|
qNextPowerOfTwo(requestedBufferSize.height())).boundedTo(nativeScreenSize);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
qCInfo(lcQpaBackingStore) << "Creating surface of" << requestedBufferSize
|
||||||
|
<< "based on requested" << m_requestedSize << "and dpr =" << devicePixelRatio;
|
||||||
|
|
||||||
|
static auto pixelFormat = QImage::toPixelFormat(QImage::Format_ARGB32_Premultiplied);
|
||||||
|
|
||||||
|
NSView *view = static_cast<QCocoaWindow *>(window()->handle())->view();
|
||||||
|
auto colorSpace = QCFType<CGColorSpaceRef>::constructFromGet(view.window.screen.colorSpace.CGColorSpace);
|
||||||
|
|
||||||
|
m_buffers.back().reset(new GraphicsBuffer(requestedBufferSize, devicePixelRatio, pixelFormat, colorSpace));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPaintDevice *QCALayerBackingStore::paintDevice()
|
||||||
|
{
|
||||||
|
Q_ASSERT(m_buffers.back());
|
||||||
|
return m_buffers.back()->asImage();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QCALayerBackingStore::endPaint()
|
||||||
|
{
|
||||||
|
qCInfo(lcQpaBackingStore) << "Paint ended with painted region" << m_paintedRegion;
|
||||||
|
m_buffers.back()->unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QCALayerBackingStore::flush(QWindow *flushedWindow, const QRegion ®ion, const QPoint &offset)
|
||||||
|
{
|
||||||
|
Q_UNUSED(region);
|
||||||
|
Q_UNUSED(offset);
|
||||||
|
|
||||||
|
if (!prepareForFlush())
|
||||||
|
return;
|
||||||
|
|
||||||
|
QMacAutoReleasePool pool;
|
||||||
|
|
||||||
|
NSView *backingStoreView = static_cast<QCocoaWindow *>(window()->handle())->view();
|
||||||
|
NSView *flushedView = static_cast<QCocoaWindow *>(flushedWindow->handle())->view();
|
||||||
|
|
||||||
|
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.
|
||||||
|
qCInfo(lcQpaBackingStore).nospace() << "Skipping flush of " << flushedView
|
||||||
|
<< ", layer already reflects back buffer";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trigger a new display cycle if there isn't one. This ensures that our layer updates
|
||||||
|
// are committed as part of a display-cycle instead of on the next runloop pass. This
|
||||||
|
// means CA won't try to throttle us if we flush too fast, and we'll coalesce our flush
|
||||||
|
// with other pending view and layer updates.
|
||||||
|
backingStoreView.window.viewsNeedDisplay = YES;
|
||||||
|
|
||||||
|
if (window()->format().swapBehavior() == QSurfaceFormat::SingleBuffer) {
|
||||||
|
// The private API [CALayer reloadValueForKeyPath:@"contents"] would be preferable,
|
||||||
|
// but barring any side effects or performance issues we opt for the hammer for now.
|
||||||
|
flushedView.layer.contents = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
qCInfo(lcQpaBackingStore) << "Flushing" << backBufferSurface
|
||||||
|
<< "to" << flushedView.layer << "of" << flushedView;
|
||||||
|
|
||||||
|
flushedView.layer.contents = backBufferSurface;
|
||||||
|
|
||||||
|
if (flushedView != backingStoreView) {
|
||||||
|
const CGSize backingStoreSize = backingStoreView.bounds.size;
|
||||||
|
flushedView.layer.contentsRect = CGRectApplyAffineTransform(
|
||||||
|
[flushedView convertRect:flushedView.bounds toView:backingStoreView],
|
||||||
|
// The contentsRect is in unit coordinate system
|
||||||
|
CGAffineTransformMakeScale(1.0 / backingStoreSize.width, 1.0 / backingStoreSize.height));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Since we may receive multiple flushes before a new frame is started, we do not
|
||||||
|
// swap any buffers just yet. Instead we check in the next beginPaint if the layer's
|
||||||
|
// surface is in use, and if so swap to an unused surface as the new back buffer.
|
||||||
|
|
||||||
|
// Note: Ideally CoreAnimation would mark a surface as in use the moment we assign
|
||||||
|
// it to a layer, but as that's not the case we may end up painting to the same back
|
||||||
|
// buffer once more if we are painting faster than CA can ship the surfaces over to
|
||||||
|
// the window server.
|
||||||
|
}
|
||||||
|
|
||||||
|
void QCALayerBackingStore::composeAndFlush(QWindow *window, const QRegion ®ion, const QPoint &offset,
|
||||||
|
QPlatformTextureList *textures, bool translucentBackground)
|
||||||
|
{
|
||||||
|
if (!prepareForFlush())
|
||||||
|
return;
|
||||||
|
|
||||||
|
QPlatformBackingStore::composeAndFlush(window, region, offset, textures, translucentBackground);
|
||||||
|
}
|
||||||
|
|
||||||
|
QPlatformGraphicsBuffer *QCALayerBackingStore::graphicsBuffer() const
|
||||||
|
{
|
||||||
|
return m_buffers.back().get();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QCALayerBackingStore::prepareForFlush()
|
||||||
|
{
|
||||||
|
if (!m_buffers.back()) {
|
||||||
|
qCWarning(lcQpaBackingStore) << "Tried to flush backingstore without painting to it first";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update dirty state of buffers based on what was painted. The back buffer will be
|
||||||
|
// less dirty, since we painted to it, while other buffers will become more dirty.
|
||||||
|
// This allows us to minimize copies between front and back buffers on swap in the
|
||||||
|
// cases where the painted region overlaps with the previous frame (front buffer).
|
||||||
|
for (const auto &buffer : m_buffers) {
|
||||||
|
if (buffer == m_buffers.back())
|
||||||
|
buffer->dirtyRegion -= m_paintedRegion;
|
||||||
|
else
|
||||||
|
buffer->dirtyRegion += m_paintedRegion;
|
||||||
|
}
|
||||||
|
|
||||||
|
// After painting, the back buffer is only guaranteed to have content for the painted
|
||||||
|
// region, and may still have dirty areas that need to be synced up with the front buffer,
|
||||||
|
// if we have one. We know that the front buffer is always up to date.
|
||||||
|
if (!m_buffers.back()->dirtyRegion.isEmpty() && m_buffers.front() != m_buffers.back()) {
|
||||||
|
QRegion preserveRegion = m_buffers.back()->dirtyRegion;
|
||||||
|
qCDebug(lcQpaBackingStore) << "Preserving" << preserveRegion << "from front to back buffer";
|
||||||
|
|
||||||
|
m_buffers.front()->lock(QPlatformGraphicsBuffer::SWReadAccess);
|
||||||
|
const QImage *frontBuffer = m_buffers.front()->asImage();
|
||||||
|
|
||||||
|
const QRect frontSurfaceBounds(QPoint(0, 0), m_buffers.front()->size());
|
||||||
|
const qreal sourceDevicePixelRatio = frontBuffer->devicePixelRatio();
|
||||||
|
|
||||||
|
m_buffers.back()->lock(QPlatformGraphicsBuffer::SWWriteAccess);
|
||||||
|
QPainter painter(m_buffers.back()->asImage());
|
||||||
|
painter.setCompositionMode(QPainter::CompositionMode_Source);
|
||||||
|
|
||||||
|
// Let painter operate in device pixels, to make it easier to compare coordinates
|
||||||
|
const qreal targetDevicePixelRatio = painter.device()->devicePixelRatio();
|
||||||
|
painter.scale(1.0 / targetDevicePixelRatio, 1.0 / targetDevicePixelRatio);
|
||||||
|
|
||||||
|
for (const QRect &rect : preserveRegion) {
|
||||||
|
QRect sourceRect(rect.topLeft() * sourceDevicePixelRatio, rect.size() * sourceDevicePixelRatio);
|
||||||
|
QRect targetRect(rect.topLeft() * targetDevicePixelRatio, rect.size() * targetDevicePixelRatio);
|
||||||
|
|
||||||
|
#ifdef QT_DEBUG
|
||||||
|
if (Q_UNLIKELY(!frontSurfaceBounds.contains(sourceRect.bottomRight()))) {
|
||||||
|
qCWarning(lcQpaBackingStore) << "Front buffer too small to preserve"
|
||||||
|
<< QRegion(sourceRect).subtracted(frontSurfaceBounds);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
painter.drawImage(targetRect, *frontBuffer, sourceRect);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_buffers.back()->unlock();
|
||||||
|
m_buffers.front()->unlock();
|
||||||
|
|
||||||
|
// The back buffer is now completely in sync, ready to be presented
|
||||||
|
m_buffers.back()->dirtyRegion = QRegion();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare for another round of painting
|
||||||
|
m_paintedRegion = QRegion();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
QCALayerBackingStore::GraphicsBuffer::GraphicsBuffer(const QSize &size, qreal devicePixelRatio,
|
||||||
|
const QPixelFormat &format, QCFType<CGColorSpaceRef> colorSpace)
|
||||||
|
: QIOSurfaceGraphicsBuffer(size, format, colorSpace)
|
||||||
|
, dirtyRegion(0, 0, size.width() / devicePixelRatio, size.height() / devicePixelRatio)
|
||||||
|
, m_devicePixelRatio(devicePixelRatio)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QImage *QCALayerBackingStore::GraphicsBuffer::asImage()
|
||||||
|
{
|
||||||
|
if (m_image.isNull()) {
|
||||||
|
qCDebug(lcQpaBackingStore) << "Setting up paint device for" << this;
|
||||||
|
CFRetain(surface());
|
||||||
|
m_image = QImage(data(), size().width(), size().height(),
|
||||||
|
bytesPerLine(), QImage::toImageFormat(format()),
|
||||||
|
QImageCleanupFunction(CFRelease), surface());
|
||||||
|
m_image.setDevicePixelRatio(m_devicePixelRatio);
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_ASSERT_X(m_image.constBits() == data(), "QCALayerBackingStore",
|
||||||
|
"IOSurfaces should have have a fixed location in memory once created");
|
||||||
|
|
||||||
|
return &m_image;
|
||||||
|
}
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -244,7 +244,7 @@ QCocoaIntegration::~QCocoaIntegration()
|
|||||||
|
|
||||||
// Delete screens in reverse order to avoid crash in case of multiple screens
|
// Delete screens in reverse order to avoid crash in case of multiple screens
|
||||||
while (!mScreens.isEmpty()) {
|
while (!mScreens.isEmpty()) {
|
||||||
destroyScreen(mScreens.takeLast());
|
QWindowSystemInterface::handleScreenRemoved(mScreens.takeLast());
|
||||||
}
|
}
|
||||||
|
|
||||||
clearToolbars();
|
clearToolbars();
|
||||||
@ -304,7 +304,7 @@ void QCocoaIntegration::updateScreens()
|
|||||||
screen = new QCocoaScreen(i);
|
screen = new QCocoaScreen(i);
|
||||||
mScreens.append(screen);
|
mScreens.append(screen);
|
||||||
qCDebug(lcQpaScreen) << "Adding" << screen;
|
qCDebug(lcQpaScreen) << "Adding" << screen;
|
||||||
screenAdded(screen);
|
QWindowSystemInterface::handleScreenAdded(screen);
|
||||||
}
|
}
|
||||||
siblings << screen;
|
siblings << screen;
|
||||||
}
|
}
|
||||||
@ -321,7 +321,7 @@ void QCocoaIntegration::updateScreens()
|
|||||||
// Prevent stale references to NSScreen during destroy
|
// Prevent stale references to NSScreen during destroy
|
||||||
screen->m_screenIndex = -1;
|
screen->m_screenIndex = -1;
|
||||||
qCDebug(lcQpaScreen) << "Removing" << screen;
|
qCDebug(lcQpaScreen) << "Removing" << screen;
|
||||||
destroyScreen(screen);
|
QWindowSystemInterface::handleScreenRemoved(screen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -407,7 +407,16 @@ QPlatformOpenGLContext *QCocoaIntegration::createPlatformOpenGLContext(QOpenGLCo
|
|||||||
|
|
||||||
QPlatformBackingStore *QCocoaIntegration::createPlatformBackingStore(QWindow *window) const
|
QPlatformBackingStore *QCocoaIntegration::createPlatformBackingStore(QWindow *window) const
|
||||||
{
|
{
|
||||||
return new QCocoaBackingStore(window);
|
QCocoaWindow *platformWindow = static_cast<QCocoaWindow*>(window->handle());
|
||||||
|
if (!platformWindow) {
|
||||||
|
qWarning() << window << "must be created before being used with a backingstore";
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (platformWindow->view().layer)
|
||||||
|
return new QCALayerBackingStore(window);
|
||||||
|
else
|
||||||
|
return new QNSWindowBackingStore(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
QAbstractEventDispatcher *QCocoaIntegration::createEventDispatcher() const
|
QAbstractEventDispatcher *QCocoaIntegration::createEventDispatcher() const
|
||||||
|
77
src/plugins/platforms/cocoa/qiosurfacegraphicsbuffer.h
Normal file
77
src/plugins/platforms/cocoa/qiosurfacegraphicsbuffer.h
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2019 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of the plugins of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL$
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 3 requirements
|
||||||
|
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 2.0 or (at your option) the GNU General
|
||||||
|
** Public license version 3 or any later version approved by the KDE Free
|
||||||
|
** Qt Foundation. The licenses are as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||||
|
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef QIOSURFACEGRAPHICSBUFFER_H
|
||||||
|
#define QIOSURFACEGRAPHICSBUFFER_H
|
||||||
|
|
||||||
|
#include <qpa/qplatformgraphicsbuffer.h>
|
||||||
|
#include <private/qcore_mac_p.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class QIOSurfaceGraphicsBuffer : public QPlatformGraphicsBuffer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QIOSurfaceGraphicsBuffer(const QSize &size, const QPixelFormat &format, QCFType<CGColorSpaceRef> colorSpace);
|
||||||
|
~QIOSurfaceGraphicsBuffer();
|
||||||
|
|
||||||
|
const uchar *data() const override;
|
||||||
|
uchar *data() override;
|
||||||
|
int bytesPerLine() const override;
|
||||||
|
|
||||||
|
IOSurfaceRef surface();
|
||||||
|
bool isInUse() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool doLock(AccessTypes access, const QRect &rect) override;
|
||||||
|
void doUnlock() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QCFType<IOSurfaceRef> m_surface;
|
||||||
|
|
||||||
|
friend QDebug operator<<(QDebug, const QIOSurfaceGraphicsBuffer *);
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifndef QT_NO_DEBUG_STREAM
|
||||||
|
QDebug operator<<(QDebug, const QIOSurfaceGraphicsBuffer *);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
#endif // QIOSURFACEGRAPHICSBUFFER_H
|
188
src/plugins/platforms/cocoa/qiosurfacegraphicsbuffer.mm
Normal file
188
src/plugins/platforms/cocoa/qiosurfacegraphicsbuffer.mm
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2019 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of the plugins of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL$
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 3 requirements
|
||||||
|
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 2.0 or (at your option) the GNU General
|
||||||
|
** Public license version 3 or any later version approved by the KDE Free
|
||||||
|
** Qt Foundation. The licenses are as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||||
|
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "qiosurfacegraphicsbuffer.h"
|
||||||
|
|
||||||
|
#include <QtCore/qdebug.h>
|
||||||
|
#include <QtCore/qloggingcategory.h>
|
||||||
|
|
||||||
|
#include <CoreGraphics/CoreGraphics.h>
|
||||||
|
#include <IOSurface/IOSurface.h>
|
||||||
|
|
||||||
|
// CGColorSpaceCopyPropertyList is available on 10.12 and above,
|
||||||
|
// but was only added in the 10.14 SDK, so declare it just in case.
|
||||||
|
extern "C" CFPropertyListRef CGColorSpaceCopyPropertyList(CGColorSpaceRef space);
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
Q_LOGGING_CATEGORY(lcQpaIOSurface, "qt.qpa.backingstore.iosurface");
|
||||||
|
|
||||||
|
QIOSurfaceGraphicsBuffer::QIOSurfaceGraphicsBuffer(const QSize &size, const QPixelFormat &format, QCFType<CGColorSpaceRef> colorSpace)
|
||||||
|
: QPlatformGraphicsBuffer(size, format)
|
||||||
|
{
|
||||||
|
const size_t width = size.width();
|
||||||
|
const size_t height = size.height();
|
||||||
|
|
||||||
|
Q_ASSERT(width <= IOSurfaceGetPropertyMaximum(kIOSurfaceWidth));
|
||||||
|
Q_ASSERT(height <= IOSurfaceGetPropertyMaximum(kIOSurfaceHeight));
|
||||||
|
|
||||||
|
static const char bytesPerElement = 4;
|
||||||
|
|
||||||
|
const size_t bytesPerRow = IOSurfaceAlignProperty(kIOSurfaceBytesPerRow, width * bytesPerElement);
|
||||||
|
const size_t totalBytes = IOSurfaceAlignProperty(kIOSurfaceAllocSize, height * bytesPerRow);
|
||||||
|
|
||||||
|
NSDictionary *options = @{
|
||||||
|
(id)kIOSurfaceWidth: @(width),
|
||||||
|
(id)kIOSurfaceHeight: @(height),
|
||||||
|
(id)kIOSurfacePixelFormat: @(unsigned('BGRA')),
|
||||||
|
(id)kIOSurfaceBytesPerElement: @(bytesPerElement),
|
||||||
|
(id)kIOSurfaceBytesPerRow: @(bytesPerRow),
|
||||||
|
(id)kIOSurfaceAllocSize: @(totalBytes),
|
||||||
|
};
|
||||||
|
|
||||||
|
m_surface = IOSurfaceCreate((CFDictionaryRef)options);
|
||||||
|
Q_ASSERT(m_surface);
|
||||||
|
|
||||||
|
Q_ASSERT(size_t(bytesPerLine()) == bytesPerRow);
|
||||||
|
Q_ASSERT(size_t(byteCount()) == totalBytes);
|
||||||
|
|
||||||
|
if (colorSpace) {
|
||||||
|
IOSurfaceSetValue(m_surface, CFSTR("IOSurfaceColorSpace"),
|
||||||
|
QCFType<CFPropertyListRef>(CGColorSpaceCopyPropertyList(colorSpace)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QIOSurfaceGraphicsBuffer::~QIOSurfaceGraphicsBuffer()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const uchar *QIOSurfaceGraphicsBuffer::data() const
|
||||||
|
{
|
||||||
|
return (const uchar *)IOSurfaceGetBaseAddress(m_surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
uchar *QIOSurfaceGraphicsBuffer::data()
|
||||||
|
{
|
||||||
|
return (uchar *)IOSurfaceGetBaseAddress(m_surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
int QIOSurfaceGraphicsBuffer::bytesPerLine() const
|
||||||
|
{
|
||||||
|
return IOSurfaceGetBytesPerRow(m_surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
IOSurfaceRef QIOSurfaceGraphicsBuffer::surface()
|
||||||
|
{
|
||||||
|
return m_surface;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QIOSurfaceGraphicsBuffer::isInUse() const
|
||||||
|
{
|
||||||
|
return IOSurfaceIsInUse(m_surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
IOSurfaceLockOptions lockOptionsForAccess(QPlatformGraphicsBuffer::AccessTypes access)
|
||||||
|
{
|
||||||
|
IOSurfaceLockOptions lockOptions = 0;
|
||||||
|
if (!(access & QPlatformGraphicsBuffer::SWWriteAccess))
|
||||||
|
lockOptions |= kIOSurfaceLockReadOnly;
|
||||||
|
return lockOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QIOSurfaceGraphicsBuffer::doLock(AccessTypes access, const QRect &rect)
|
||||||
|
{
|
||||||
|
Q_UNUSED(rect);
|
||||||
|
Q_ASSERT(!isLocked());
|
||||||
|
|
||||||
|
qCDebug(lcQpaIOSurface) << "Locking" << this << "for" << access;
|
||||||
|
|
||||||
|
// FIXME: Teach QPlatformBackingStore::composeAndFlush about non-2D texture
|
||||||
|
// targets, so that we can use CGLTexImageIOSurface2D to support TextureAccess.
|
||||||
|
if (access & (TextureAccess | HWCompositor))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto lockOptions = lockOptionsForAccess(access);
|
||||||
|
|
||||||
|
// Try without read-back first
|
||||||
|
lockOptions |= kIOSurfaceLockAvoidSync;
|
||||||
|
kern_return_t ret = IOSurfaceLock(m_surface, lockOptions, nullptr);
|
||||||
|
if (ret == kIOSurfaceSuccess)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (ret == kIOReturnCannotLock) {
|
||||||
|
qCWarning(lcQpaIOSurface) << "Locking of" << this << "requires read-back";
|
||||||
|
lockOptions ^= kIOSurfaceLockAvoidSync;
|
||||||
|
ret = IOSurfaceLock(m_surface, lockOptions, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret != kIOSurfaceSuccess) {
|
||||||
|
qCWarning(lcQpaIOSurface) << "Failed to lock" << this << ret;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QIOSurfaceGraphicsBuffer::doUnlock()
|
||||||
|
{
|
||||||
|
qCDebug(lcQpaIOSurface) << "Unlocking" << this << "from" << isLocked();
|
||||||
|
|
||||||
|
auto lockOptions = lockOptionsForAccess(isLocked());
|
||||||
|
bool success = IOSurfaceUnlock(m_surface, lockOptions, nullptr) == kIOSurfaceSuccess;
|
||||||
|
Q_ASSERT_X(success, "QIOSurfaceGraphicsBuffer", "Unlocking surface should succeed");
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef QT_NO_DEBUG_STREAM
|
||||||
|
QDebug operator<<(QDebug debug, const QIOSurfaceGraphicsBuffer *graphicsBuffer)
|
||||||
|
{
|
||||||
|
QDebugStateSaver saver(debug);
|
||||||
|
debug.nospace();
|
||||||
|
debug << "QIOSurfaceGraphicsBuffer(" << (const void *)graphicsBuffer;
|
||||||
|
if (graphicsBuffer) {
|
||||||
|
debug << ", surface=" << graphicsBuffer->m_surface;
|
||||||
|
debug << ", size=" << graphicsBuffer->size();
|
||||||
|
debug << ", isLocked=" << bool(graphicsBuffer->isLocked());
|
||||||
|
debug << ", isInUse=" << graphicsBuffer->isInUse();
|
||||||
|
}
|
||||||
|
debug << ')';
|
||||||
|
return debug;
|
||||||
|
}
|
||||||
|
#endif // !QT_NO_DEBUG_STREAM
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
@ -163,6 +163,13 @@
|
|||||||
return NSViewLayerContentsRedrawDuringViewResize;
|
return NSViewLayerContentsRedrawDuringViewResize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSViewLayerContentsPlacement)layerContentsPlacement
|
||||||
|
{
|
||||||
|
// Always place the layer at top left without any automatic scaling,
|
||||||
|
// so that we can re-use larger layers when resizing a window down.
|
||||||
|
return NSViewLayerContentsPlacementTopLeft;
|
||||||
|
}
|
||||||
|
|
||||||
- (void)updateMetalLayerDrawableSize:(CAMetalLayer *)layer
|
- (void)updateMetalLayerDrawableSize:(CAMetalLayer *)layer
|
||||||
{
|
{
|
||||||
CGSize drawableSize = layer.bounds.size;
|
CGSize drawableSize = layer.bounds.size;
|
||||||
|
@ -44,6 +44,7 @@
|
|||||||
|
|
||||||
#include <QtGui/QOpenGLContext>
|
#include <QtGui/QOpenGLContext>
|
||||||
#include <qpa/qplatformopenglcontext.h>
|
#include <qpa/qplatformopenglcontext.h>
|
||||||
|
#include <qpa/qwindowsysteminterface.h>
|
||||||
#include <QtGui/QScreen>
|
#include <QtGui/QScreen>
|
||||||
|
|
||||||
#include <QtEglSupport/private/qeglplatformcontext_p.h>
|
#include <QtEglSupport/private/qeglplatformcontext_p.h>
|
||||||
@ -248,7 +249,7 @@ QPlatformOpenGLContext *QDirectFbIntegrationEGL::createPlatformOpenGLContext(QOp
|
|||||||
void QDirectFbIntegrationEGL::initializeScreen()
|
void QDirectFbIntegrationEGL::initializeScreen()
|
||||||
{
|
{
|
||||||
m_primaryScreen.reset(new QDirectFbScreenEGL(0));
|
m_primaryScreen.reset(new QDirectFbScreenEGL(0));
|
||||||
screenAdded(m_primaryScreen.data());
|
QWindowSystemInterface::handleScreenAdded(m_primaryScreen.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QDirectFbIntegrationEGL::hasCapability(QPlatformIntegration::Capability cap) const
|
bool QDirectFbIntegrationEGL::hasCapability(QPlatformIntegration::Capability cap) const
|
||||||
|
@ -56,6 +56,7 @@
|
|||||||
#include <QtCore/QThread>
|
#include <QtCore/QThread>
|
||||||
#include <QtCore/QAbstractEventDispatcher>
|
#include <QtCore/QAbstractEventDispatcher>
|
||||||
#include <qpa/qplatforminputcontextfactory_p.h>
|
#include <qpa/qplatforminputcontextfactory_p.h>
|
||||||
|
#include <qpa/qwindowsysteminterface.h>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
@ -113,7 +114,7 @@ void QDirectFbIntegration::initializeDirectFB()
|
|||||||
void QDirectFbIntegration::initializeScreen()
|
void QDirectFbIntegration::initializeScreen()
|
||||||
{
|
{
|
||||||
m_primaryScreen.reset(new QDirectFbScreen(0));
|
m_primaryScreen.reset(new QDirectFbScreen(0));
|
||||||
screenAdded(m_primaryScreen.data());
|
QWindowSystemInterface::handleScreenAdded(m_primaryScreen.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
void QDirectFbIntegration::initializeInput()
|
void QDirectFbIntegration::initializeInput()
|
||||||
|
@ -200,10 +200,8 @@ void QEglFSDeviceIntegration::screenInit()
|
|||||||
void QEglFSDeviceIntegration::screenDestroy()
|
void QEglFSDeviceIntegration::screenDestroy()
|
||||||
{
|
{
|
||||||
QGuiApplication *app = qGuiApp;
|
QGuiApplication *app = qGuiApp;
|
||||||
QEglFSIntegration *platformIntegration = static_cast<QEglFSIntegration *>(
|
|
||||||
QGuiApplicationPrivate::platformIntegration());
|
|
||||||
while (!app->screens().isEmpty())
|
while (!app->screens().isEmpty())
|
||||||
platformIntegration->removeScreen(app->screens().constLast()->handle());
|
QWindowSystemInterface::handleScreenRemoved(app->screens().constLast()->handle());
|
||||||
}
|
}
|
||||||
|
|
||||||
QSizeF QEglFSDeviceIntegration::physicalScreenSize() const
|
QSizeF QEglFSDeviceIntegration::physicalScreenSize() const
|
||||||
|
@ -120,16 +120,6 @@ QEglFSIntegration::QEglFSIntegration()
|
|||||||
initResources();
|
initResources();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QEglFSIntegration::addScreen(QPlatformScreen *screen, bool isPrimary)
|
|
||||||
{
|
|
||||||
screenAdded(screen, isPrimary);
|
|
||||||
}
|
|
||||||
|
|
||||||
void QEglFSIntegration::removeScreen(QPlatformScreen *screen)
|
|
||||||
{
|
|
||||||
destroyScreen(screen);
|
|
||||||
}
|
|
||||||
|
|
||||||
void QEglFSIntegration::initialize()
|
void QEglFSIntegration::initialize()
|
||||||
{
|
{
|
||||||
qt_egl_device_integration()->platformInit();
|
qt_egl_device_integration()->platformInit();
|
||||||
@ -147,7 +137,7 @@ void QEglFSIntegration::initialize()
|
|||||||
m_vtHandler.reset(new QFbVtHandler);
|
m_vtHandler.reset(new QFbVtHandler);
|
||||||
|
|
||||||
if (qt_egl_device_integration()->usesDefaultScreen())
|
if (qt_egl_device_integration()->usesDefaultScreen())
|
||||||
addScreen(new QEglFSScreen(display()));
|
QWindowSystemInterface::handleScreenAdded(new QEglFSScreen(display()));
|
||||||
else
|
else
|
||||||
qt_egl_device_integration()->screenInit();
|
qt_egl_device_integration()->screenInit();
|
||||||
|
|
||||||
|
@ -103,9 +103,6 @@ public:
|
|||||||
|
|
||||||
QFbVtHandler *vtHandler() { return m_vtHandler.data(); }
|
QFbVtHandler *vtHandler() { return m_vtHandler.data(); }
|
||||||
|
|
||||||
void addScreen(QPlatformScreen *screen, bool isPrimary = false);
|
|
||||||
void removeScreen(QPlatformScreen *screen);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
EGLNativeDisplayType nativeDisplay() const;
|
EGLNativeDisplayType nativeDisplay() const;
|
||||||
void createInputHandlers();
|
void createInputHandlers();
|
||||||
|
@ -45,6 +45,8 @@
|
|||||||
#include <QtEglSupport/private/qeglconvenience_p.h>
|
#include <QtEglSupport/private/qeglconvenience_p.h>
|
||||||
#include <QtEglSupport/private/qeglplatformcontext_p.h>
|
#include <QtEglSupport/private/qeglplatformcontext_p.h>
|
||||||
|
|
||||||
|
#include <qpa/qwindowsysteminterface.h>
|
||||||
|
|
||||||
#include <QtCore/QJsonDocument>
|
#include <QtCore/QJsonDocument>
|
||||||
#include <QtCore/QJsonArray>
|
#include <QtCore/QJsonArray>
|
||||||
#include <QtCore/QJsonParseError>
|
#include <QtCore/QJsonParseError>
|
||||||
@ -80,8 +82,6 @@ bool QEglFSEmulatorIntegration::usesDefaultScreen()
|
|||||||
|
|
||||||
void QEglFSEmulatorIntegration::screenInit()
|
void QEglFSEmulatorIntegration::screenInit()
|
||||||
{
|
{
|
||||||
QEglFSIntegration *integration = static_cast<QEglFSIntegration *>(QGuiApplicationPrivate::platformIntegration());
|
|
||||||
|
|
||||||
// Use qgsGetDisplays() call to retrieve the available screens from the Emulator
|
// Use qgsGetDisplays() call to retrieve the available screens from the Emulator
|
||||||
if (getDisplays) {
|
if (getDisplays) {
|
||||||
QByteArray displaysInfo = getDisplays();
|
QByteArray displaysInfo = getDisplays();
|
||||||
@ -93,7 +93,7 @@ void QEglFSEmulatorIntegration::screenInit()
|
|||||||
QJsonArray screenArray = displaysDocument.array();
|
QJsonArray screenArray = displaysDocument.array();
|
||||||
for (auto screenValue : screenArray) {
|
for (auto screenValue : screenArray) {
|
||||||
if (screenValue.isObject())
|
if (screenValue.isObject())
|
||||||
integration->addScreen(new QEglFSEmulatorScreen(screenValue.toObject()));
|
QWindowSystemInterface::handleScreenAdded(new QEglFSEmulatorScreen(screenValue.toObject()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -260,7 +260,7 @@ QKmsDevice *QEglFSKmsEglDeviceIntegration::createDevice()
|
|||||||
if (Q_UNLIKELY(!deviceName))
|
if (Q_UNLIKELY(!deviceName))
|
||||||
qFatal("Failed to query device name from EGLDevice");
|
qFatal("Failed to query device name from EGLDevice");
|
||||||
|
|
||||||
return new QEglFSKmsEglDevice(this, screenConfig(), deviceName);
|
return new QEglFSKmsEglDevice(this, screenConfig(), QLatin1String(deviceName));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QEglFSKmsEglDeviceIntegration::query_egl_device()
|
bool QEglFSKmsEglDeviceIntegration::query_egl_device()
|
||||||
|
@ -58,7 +58,7 @@ void QEglFSKmsDevice::registerScreen(QPlatformScreen *screen,
|
|||||||
QEglFSKmsScreen *s = static_cast<QEglFSKmsScreen *>(screen);
|
QEglFSKmsScreen *s = static_cast<QEglFSKmsScreen *>(screen);
|
||||||
s->setVirtualPosition(virtualPos);
|
s->setVirtualPosition(virtualPos);
|
||||||
s->setVirtualSiblings(virtualSiblings);
|
s->setVirtualSiblings(virtualSiblings);
|
||||||
static_cast<QEglFSIntegration *>(QGuiApplicationPrivate::platformIntegration())->addScreen(s, isPrimary);
|
QWindowSystemInterface::handleScreenAdded(s, isPrimary);
|
||||||
}
|
}
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -49,6 +49,7 @@
|
|||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <qpa/qplatformwindow.h>
|
#include <qpa/qplatformwindow.h>
|
||||||
|
#include <qpa/qwindowsysteminterface.h>
|
||||||
#include <QtEventDispatcherSupport/private/qgenericunixeventdispatcher_p.h>
|
#include <QtEventDispatcherSupport/private/qgenericunixeventdispatcher_p.h>
|
||||||
|
|
||||||
#include <Application.h>
|
#include <Application.h>
|
||||||
@ -81,12 +82,12 @@ QHaikuIntegration::QHaikuIntegration(const QStringList ¶meters)
|
|||||||
m_services = new QHaikuServices;
|
m_services = new QHaikuServices;
|
||||||
|
|
||||||
// notify system about available screen
|
// notify system about available screen
|
||||||
screenAdded(m_screen);
|
QWindowSystemInterface::handleScreenAdded(m_screen);
|
||||||
}
|
}
|
||||||
|
|
||||||
QHaikuIntegration::~QHaikuIntegration()
|
QHaikuIntegration::~QHaikuIntegration()
|
||||||
{
|
{
|
||||||
destroyScreen(m_screen);
|
QWindowSystemInterface::handleScreenRemoved(m_screen);
|
||||||
m_screen = nullptr;
|
m_screen = nullptr;
|
||||||
|
|
||||||
delete m_services;
|
delete m_services;
|
||||||
|
@ -51,7 +51,7 @@
|
|||||||
|
|
||||||
#include <QtGui/private/qguiapplication_p.h>
|
#include <QtGui/private/qguiapplication_p.h>
|
||||||
#include <qpa/qplatforminputcontextfactory_p.h>
|
#include <qpa/qplatforminputcontextfactory_p.h>
|
||||||
|
#include <qpa/qwindowsysteminterface.h>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
@ -64,13 +64,13 @@ QIntegrityFbIntegration::QIntegrityFbIntegration(const QStringList ¶mList)
|
|||||||
|
|
||||||
QIntegrityFbIntegration::~QIntegrityFbIntegration()
|
QIntegrityFbIntegration::~QIntegrityFbIntegration()
|
||||||
{
|
{
|
||||||
destroyScreen(m_primaryScreen);
|
QWindowSystemInterface::handleScreenRemoved(m_primaryScreen);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QIntegrityFbIntegration::initialize()
|
void QIntegrityFbIntegration::initialize()
|
||||||
{
|
{
|
||||||
if (m_primaryScreen->initialize())
|
if (m_primaryScreen->initialize())
|
||||||
screenAdded(m_primaryScreen);
|
QWindowSystemInterface::handleScreenAdded(m_primaryScreen);
|
||||||
else
|
else
|
||||||
qWarning("integrityfb: Failed to initialize screen");
|
qWarning("integrityfb: Failed to initialize screen");
|
||||||
|
|
||||||
|
@ -92,10 +92,6 @@ public:
|
|||||||
QPlatformAccessibility *accessibility() const override;
|
QPlatformAccessibility *accessibility() const override;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Called from Objective-C class QIOSScreenTracker, which can't be friended
|
|
||||||
void addScreen(QPlatformScreen *screen) { screenAdded(screen); }
|
|
||||||
void destroyScreen(QPlatformScreen *screen) { QPlatformIntegration::destroyScreen(screen); }
|
|
||||||
|
|
||||||
void beep() const override;
|
void beep() const override;
|
||||||
|
|
||||||
static QIOSIntegration *instance();
|
static QIOSIntegration *instance();
|
||||||
|
@ -107,7 +107,7 @@ void QIOSIntegration::initialize()
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (UIScreen *screen in screens)
|
for (UIScreen *screen in screens)
|
||||||
addScreen(new QIOSScreen(screen));
|
QWindowSystemInterface::handleScreenAdded(new QIOSScreen(screen));
|
||||||
|
|
||||||
// Depends on a primary screen being present
|
// Depends on a primary screen being present
|
||||||
m_inputContext = new QIOSInputContext;
|
m_inputContext = new QIOSInputContext;
|
||||||
@ -143,7 +143,7 @@ QIOSIntegration::~QIOSIntegration()
|
|||||||
m_inputContext = 0;
|
m_inputContext = 0;
|
||||||
|
|
||||||
foreach (QScreen *screen, QGuiApplication::screens())
|
foreach (QScreen *screen, QGuiApplication::screens())
|
||||||
destroyScreen(screen->handle());
|
QWindowSystemInterface::handleScreenRemoved(screen->handle());
|
||||||
|
|
||||||
delete m_platformServices;
|
delete m_platformServices;
|
||||||
m_platformServices = 0;
|
m_platformServices = 0;
|
||||||
|
@ -50,6 +50,7 @@
|
|||||||
|
|
||||||
#include <QtGui/private/qwindow_p.h>
|
#include <QtGui/private/qwindow_p.h>
|
||||||
#include <private/qcoregraphics_p.h>
|
#include <private/qcoregraphics_p.h>
|
||||||
|
#include <qpa/qwindowsysteminterface.h>
|
||||||
|
|
||||||
#include <sys/sysctl.h>
|
#include <sys/sysctl.h>
|
||||||
|
|
||||||
@ -105,10 +106,10 @@ static QIOSScreen* qtPlatformScreenFor(UIScreen *uiScreen)
|
|||||||
|
|
||||||
+ (void)screenConnected:(NSNotification*)notification
|
+ (void)screenConnected:(NSNotification*)notification
|
||||||
{
|
{
|
||||||
QIOSIntegration *integration = QIOSIntegration::instance();
|
Q_ASSERT_X(QIOSIntegration::instance(), Q_FUNC_INFO,
|
||||||
Q_ASSERT_X(integration, Q_FUNC_INFO, "Screen connected before QIOSIntegration creation");
|
"Screen connected before QIOSIntegration creation");
|
||||||
|
|
||||||
integration->addScreen(new QIOSScreen([notification object]));
|
QWindowSystemInterface::handleScreenAdded(new QIOSScreen([notification object]));
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (void)screenDisconnected:(NSNotification*)notification
|
+ (void)screenDisconnected:(NSNotification*)notification
|
||||||
@ -116,8 +117,7 @@ static QIOSScreen* qtPlatformScreenFor(UIScreen *uiScreen)
|
|||||||
QIOSScreen *screen = qtPlatformScreenFor([notification object]);
|
QIOSScreen *screen = qtPlatformScreenFor([notification object]);
|
||||||
Q_ASSERT_X(screen, Q_FUNC_INFO, "Screen disconnected that we didn't know about");
|
Q_ASSERT_X(screen, Q_FUNC_INFO, "Screen disconnected that we didn't know about");
|
||||||
|
|
||||||
QIOSIntegration *integration = QIOSIntegration::instance();
|
QWindowSystemInterface::handleScreenRemoved(screen);
|
||||||
integration->destroyScreen(screen);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (void)screenModeChanged:(NSNotification*)notification
|
+ (void)screenModeChanged:(NSNotification*)notification
|
||||||
|
@ -54,6 +54,7 @@
|
|||||||
|
|
||||||
#include <QtGui/private/qguiapplication_p.h>
|
#include <QtGui/private/qguiapplication_p.h>
|
||||||
#include <qpa/qplatforminputcontextfactory_p.h>
|
#include <qpa/qplatforminputcontextfactory_p.h>
|
||||||
|
#include <qpa/qwindowsysteminterface.h>
|
||||||
|
|
||||||
#if QT_CONFIG(libinput)
|
#if QT_CONFIG(libinput)
|
||||||
#include <QtInputSupport/private/qlibinputhandler_p.h>
|
#include <QtInputSupport/private/qlibinputhandler_p.h>
|
||||||
@ -89,13 +90,13 @@ QLinuxFbIntegration::QLinuxFbIntegration(const QStringList ¶mList)
|
|||||||
|
|
||||||
QLinuxFbIntegration::~QLinuxFbIntegration()
|
QLinuxFbIntegration::~QLinuxFbIntegration()
|
||||||
{
|
{
|
||||||
destroyScreen(m_primaryScreen);
|
QWindowSystemInterface::handleScreenRemoved(m_primaryScreen);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QLinuxFbIntegration::initialize()
|
void QLinuxFbIntegration::initialize()
|
||||||
{
|
{
|
||||||
if (m_primaryScreen->initialize())
|
if (m_primaryScreen->initialize())
|
||||||
screenAdded(m_primaryScreen);
|
QWindowSystemInterface::handleScreenAdded(m_primaryScreen);
|
||||||
else
|
else
|
||||||
qWarning("linuxfb: Failed to initialize screen");
|
qWarning("linuxfb: Failed to initialize screen");
|
||||||
|
|
||||||
|
@ -43,6 +43,7 @@
|
|||||||
#include <QtGui/private/qpixmap_raster_p.h>
|
#include <QtGui/private/qpixmap_raster_p.h>
|
||||||
#include <QtGui/private/qguiapplication_p.h>
|
#include <QtGui/private/qguiapplication_p.h>
|
||||||
#include <qpa/qplatformwindow.h>
|
#include <qpa/qplatformwindow.h>
|
||||||
|
#include <qpa/qwindowsysteminterface.h>
|
||||||
|
|
||||||
#include <QtFontDatabaseSupport/private/qfreetypefontdatabase_p.h>
|
#include <QtFontDatabaseSupport/private/qfreetypefontdatabase_p.h>
|
||||||
#if defined(Q_OS_WINRT)
|
#if defined(Q_OS_WINRT)
|
||||||
@ -108,7 +109,7 @@ QMinimalIntegration::QMinimalIntegration(const QStringList ¶meters)
|
|||||||
mPrimaryScreen->mDepth = 32;
|
mPrimaryScreen->mDepth = 32;
|
||||||
mPrimaryScreen->mFormat = QImage::Format_ARGB32_Premultiplied;
|
mPrimaryScreen->mFormat = QImage::Format_ARGB32_Premultiplied;
|
||||||
|
|
||||||
screenAdded(mPrimaryScreen);
|
QWindowSystemInterface::handleScreenAdded(mPrimaryScreen);
|
||||||
}
|
}
|
||||||
|
|
||||||
QMinimalIntegration::~QMinimalIntegration()
|
QMinimalIntegration::~QMinimalIntegration()
|
||||||
|
@ -58,6 +58,7 @@
|
|||||||
#include <QtGui/QSurfaceFormat>
|
#include <QtGui/QSurfaceFormat>
|
||||||
#include <QtGui/QOpenGLContext>
|
#include <QtGui/QOpenGLContext>
|
||||||
#include <QtGui/QScreen>
|
#include <QtGui/QScreen>
|
||||||
|
#include <qpa/qwindowsysteminterface.h>
|
||||||
|
|
||||||
// this is where EGL headers are pulled in, make sure it is last
|
// this is where EGL headers are pulled in, make sure it is last
|
||||||
#include "qminimaleglscreen.h"
|
#include "qminimaleglscreen.h"
|
||||||
@ -90,7 +91,7 @@ protected:
|
|||||||
QMinimalEglIntegration::QMinimalEglIntegration()
|
QMinimalEglIntegration::QMinimalEglIntegration()
|
||||||
: mFontDb(new QGenericUnixFontDatabase()), mScreen(new QMinimalEglScreen(EGL_DEFAULT_DISPLAY))
|
: mFontDb(new QGenericUnixFontDatabase()), mScreen(new QMinimalEglScreen(EGL_DEFAULT_DISPLAY))
|
||||||
{
|
{
|
||||||
screenAdded(mScreen);
|
QWindowSystemInterface::handleScreenAdded(mScreen);
|
||||||
|
|
||||||
#ifdef QEGL_EXTRA_DEBUG
|
#ifdef QEGL_EXTRA_DEBUG
|
||||||
qWarning("QMinimalEglIntegration\n");
|
qWarning("QMinimalEglIntegration\n");
|
||||||
@ -99,7 +100,7 @@ QMinimalEglIntegration::QMinimalEglIntegration()
|
|||||||
|
|
||||||
QMinimalEglIntegration::~QMinimalEglIntegration()
|
QMinimalEglIntegration::~QMinimalEglIntegration()
|
||||||
{
|
{
|
||||||
destroyScreen(mScreen);
|
QWindowSystemInterface::handleScreenRemoved(mScreen);
|
||||||
delete mFontDb;
|
delete mFontDb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,6 +58,7 @@
|
|||||||
#include <qpa/qplatformnativeinterface.h>
|
#include <qpa/qplatformnativeinterface.h>
|
||||||
#include <qpa/qplatforminputcontextfactory_p.h>
|
#include <qpa/qplatforminputcontextfactory_p.h>
|
||||||
#include <qpa/qplatforminputcontext.h>
|
#include <qpa/qplatforminputcontext.h>
|
||||||
|
#include <qpa/qwindowsysteminterface.h>
|
||||||
#include <QtEglSupport/private/qeglconvenience_p.h>
|
#include <QtEglSupport/private/qeglconvenience_p.h>
|
||||||
#include <QtEglSupport/private/qeglpbuffer_p.h>
|
#include <QtEglSupport/private/qeglpbuffer_p.h>
|
||||||
#include <QtFontDatabaseSupport/private/qgenericunixfontdatabase_p.h>
|
#include <QtFontDatabaseSupport/private/qgenericunixfontdatabase_p.h>
|
||||||
@ -149,12 +150,12 @@ void QMirClientClientIntegration::initialize()
|
|||||||
// Init the ScreenObserver
|
// Init the ScreenObserver
|
||||||
mScreenObserver.reset(new QMirClientScreenObserver(mMirConnection));
|
mScreenObserver.reset(new QMirClientScreenObserver(mMirConnection));
|
||||||
connect(mScreenObserver.data(), &QMirClientScreenObserver::screenAdded,
|
connect(mScreenObserver.data(), &QMirClientScreenObserver::screenAdded,
|
||||||
[this](QMirClientScreen *screen) { this->screenAdded(screen); });
|
[this](QMirClientScreen *screen) { QWindowSystemInterface::handleScreenAdded(screen); });
|
||||||
connect(mScreenObserver.data(), &QMirClientScreenObserver::screenRemoved,
|
connect(mScreenObserver.data(), &QMirClientScreenObserver::screenRemoved,
|
||||||
this, &QMirClientClientIntegration::destroyScreen);
|
this, &QMirClientClientIntegration::destroyScreen);
|
||||||
|
|
||||||
Q_FOREACH (auto screen, mScreenObserver->screens()) {
|
Q_FOREACH (auto screen, mScreenObserver->screens()) {
|
||||||
screenAdded(screen);
|
QWindowSystemInterface::handleScreenAdded(screen);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize input.
|
// Initialize input.
|
||||||
@ -392,7 +393,7 @@ void QMirClientClientIntegration::destroyScreen(QMirClientScreen *screen)
|
|||||||
#if QT_VERSION < QT_VERSION_CHECK(5, 5, 0)
|
#if QT_VERSION < QT_VERSION_CHECK(5, 5, 0)
|
||||||
delete screen;
|
delete screen;
|
||||||
#else
|
#else
|
||||||
QPlatformIntegration::destroyScreen(screen);
|
QWindowSystemInterface::handleScreenRemoved(screen);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,6 +63,7 @@
|
|||||||
#include <qpa/qplatforminputcontextfactory_p.h>
|
#include <qpa/qplatforminputcontextfactory_p.h>
|
||||||
#include <qpa/qplatforminputcontext.h>
|
#include <qpa/qplatforminputcontext.h>
|
||||||
#include <qpa/qplatformtheme.h>
|
#include <qpa/qplatformtheme.h>
|
||||||
|
#include <qpa/qwindowsysteminterface.h>
|
||||||
|
|
||||||
#include <qpa/qplatformservices.h>
|
#include <qpa/qplatformservices.h>
|
||||||
|
|
||||||
@ -121,7 +122,7 @@ QOffscreenIntegration::QOffscreenIntegration()
|
|||||||
#endif
|
#endif
|
||||||
m_services.reset(new QPlatformServices);
|
m_services.reset(new QPlatformServices);
|
||||||
|
|
||||||
screenAdded(new QOffscreenScreen);
|
QWindowSystemInterface::handleScreenAdded(new QOffscreenScreen);
|
||||||
}
|
}
|
||||||
|
|
||||||
QOffscreenIntegration::~QOffscreenIntegration()
|
QOffscreenIntegration::~QOffscreenIntegration()
|
||||||
|
@ -50,6 +50,7 @@
|
|||||||
#include <QtGui/private/qguiapplication_p.h>
|
#include <QtGui/private/qguiapplication_p.h>
|
||||||
#include <QtGui/QOpenGLContext>
|
#include <QtGui/QOpenGLContext>
|
||||||
#include <QtGui/QScreen>
|
#include <QtGui/QScreen>
|
||||||
|
#include <qpa/qwindowsysteminterface.h>
|
||||||
|
|
||||||
#include <QtEventDispatcherSupport/private/qgenericunixeventdispatcher_p.h>
|
#include <QtEventDispatcherSupport/private/qgenericunixeventdispatcher_p.h>
|
||||||
#include <QtFontDatabaseSupport/private/qgenericunixfontdatabase_p.h>
|
#include <QtFontDatabaseSupport/private/qgenericunixfontdatabase_p.h>
|
||||||
@ -135,13 +136,3 @@ QPlatformPrinterSupport * QOpenWFDIntegration::printerSupport() const
|
|||||||
{
|
{
|
||||||
return mPrinterSupport;
|
return mPrinterSupport;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QOpenWFDIntegration::addScreen(QOpenWFDScreen *screen)
|
|
||||||
{
|
|
||||||
screenAdded(screen);
|
|
||||||
}
|
|
||||||
|
|
||||||
void QOpenWFDIntegration::destroyScreen(QOpenWFDScreen *screen)
|
|
||||||
{
|
|
||||||
QPlatformIntegration::destroyScreen(screen);
|
|
||||||
}
|
|
||||||
|
@ -68,8 +68,6 @@ public:
|
|||||||
|
|
||||||
QPlatformPrinterSupport *printerSupport() const;
|
QPlatformPrinterSupport *printerSupport() const;
|
||||||
|
|
||||||
void addScreen(QOpenWFDScreen *screen);
|
|
||||||
void destroyScreen(QOpenWFDScreen *screen);
|
|
||||||
private:
|
private:
|
||||||
QList<QPlatformScreen *> mScreens;
|
QList<QPlatformScreen *> mScreens;
|
||||||
QList<QOpenWFDDevice *>mDevices;
|
QList<QOpenWFDDevice *>mDevices;
|
||||||
|
@ -133,7 +133,7 @@ void QOpenWFDPort::attach()
|
|||||||
wfdBindPipelineToPort(mDevice->handle(),mPort,mPipeline);
|
wfdBindPipelineToPort(mDevice->handle(),mPort,mPipeline);
|
||||||
|
|
||||||
mScreen = new QOpenWFDScreen(this);
|
mScreen = new QOpenWFDScreen(this);
|
||||||
mDevice->integration()->addScreen(mScreen);
|
QWindowSystemInterface::handleScreenAdded(mScreen);
|
||||||
mAttached = true;
|
mAttached = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,7 +145,7 @@ void QOpenWFDPort::detach()
|
|||||||
mAttached = false;
|
mAttached = false;
|
||||||
mOn = false;
|
mOn = false;
|
||||||
|
|
||||||
mDevice->integration()->destroyScreen(mScreen);
|
QWindowSystemInterface::handleScreenRemoved(mScreen);
|
||||||
|
|
||||||
wfdDestroyPipeline(mDevice->handle(),mPipeline);
|
wfdDestroyPipeline(mDevice->handle(),mPipeline);
|
||||||
mPipelineId = WFD_INVALID_PIPELINE_ID;
|
mPipelineId = WFD_INVALID_PIPELINE_ID;
|
||||||
|
@ -649,7 +649,7 @@ void QQnxIntegration::createDisplay(screen_display_t display, bool isPrimary)
|
|||||||
{
|
{
|
||||||
QQnxScreen *screen = new QQnxScreen(m_screenContext, display, isPrimary);
|
QQnxScreen *screen = new QQnxScreen(m_screenContext, display, isPrimary);
|
||||||
m_screens.append(screen);
|
m_screens.append(screen);
|
||||||
screenAdded(screen);
|
QWindowSystemInterface::handleScreenAdded(screen);
|
||||||
screen->adjustOrientation();
|
screen->adjustOrientation();
|
||||||
|
|
||||||
QObject::connect(m_screenEventHandler, SIGNAL(newWindowCreated(void*)),
|
QObject::connect(m_screenEventHandler, SIGNAL(newWindowCreated(void*)),
|
||||||
@ -669,14 +669,14 @@ void QQnxIntegration::removeDisplay(QQnxScreen *screen)
|
|||||||
Q_CHECK_PTR(screen);
|
Q_CHECK_PTR(screen);
|
||||||
Q_ASSERT(m_screens.contains(screen));
|
Q_ASSERT(m_screens.contains(screen));
|
||||||
m_screens.removeAll(screen);
|
m_screens.removeAll(screen);
|
||||||
destroyScreen(screen);
|
QWindowSystemInterface::handleScreenRemoved(screen);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QQnxIntegration::destroyDisplays()
|
void QQnxIntegration::destroyDisplays()
|
||||||
{
|
{
|
||||||
qIntegrationDebug();
|
qIntegrationDebug();
|
||||||
Q_FOREACH (QQnxScreen *screen, m_screens) {
|
Q_FOREACH (QQnxScreen *screen, m_screens) {
|
||||||
QPlatformIntegration::destroyScreen(screen);
|
QWindowSystemInterface::handleScreenRemoved(screen);
|
||||||
}
|
}
|
||||||
m_screens.clear();
|
m_screens.clear();
|
||||||
}
|
}
|
||||||
|
@ -52,6 +52,7 @@
|
|||||||
#include <QtGui/private/qguiapplication_p.h>
|
#include <QtGui/private/qguiapplication_p.h>
|
||||||
#include <qpa/qplatforminputcontextfactory_p.h>
|
#include <qpa/qplatforminputcontextfactory_p.h>
|
||||||
#include <private/qinputdevicemanager_p_p.h>
|
#include <private/qinputdevicemanager_p_p.h>
|
||||||
|
#include <qpa/qwindowsysteminterface.h>
|
||||||
|
|
||||||
#include <QtCore/QRegularExpression>
|
#include <QtCore/QRegularExpression>
|
||||||
|
|
||||||
@ -77,13 +78,13 @@ QVncIntegration::QVncIntegration(const QStringList ¶mList)
|
|||||||
QVncIntegration::~QVncIntegration()
|
QVncIntegration::~QVncIntegration()
|
||||||
{
|
{
|
||||||
delete m_server;
|
delete m_server;
|
||||||
destroyScreen(m_primaryScreen);
|
QWindowSystemInterface::handleScreenRemoved(m_primaryScreen);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QVncIntegration::initialize()
|
void QVncIntegration::initialize()
|
||||||
{
|
{
|
||||||
if (m_primaryScreen->initialize())
|
if (m_primaryScreen->initialize())
|
||||||
screenAdded(m_primaryScreen);
|
QWindowSystemInterface::handleScreenAdded(m_primaryScreen);
|
||||||
else
|
else
|
||||||
qWarning("vnc: Failed to initialize screen");
|
qWarning("vnc: Failed to initialize screen");
|
||||||
|
|
||||||
|
@ -98,7 +98,10 @@ QWasmIntegration::QWasmIntegration()
|
|||||||
QWasmIntegration::~QWasmIntegration()
|
QWasmIntegration::~QWasmIntegration()
|
||||||
{
|
{
|
||||||
delete m_fontDb;
|
delete m_fontDb;
|
||||||
qDeleteAll(m_screens);
|
|
||||||
|
while (!m_screens.isEmpty())
|
||||||
|
QWindowSystemInterface::handleScreenRemoved(m_screens.takeLast());
|
||||||
|
|
||||||
s_instance = nullptr;
|
s_instance = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,7 +194,7 @@ void QWasmIntegration::addScreen(const QString &canvasId)
|
|||||||
QWasmScreen *screen = new QWasmScreen(canvasId);
|
QWasmScreen *screen = new QWasmScreen(canvasId);
|
||||||
m_clipboard->installEventHandlers(canvasId);
|
m_clipboard->installEventHandlers(canvasId);
|
||||||
m_screens.append(screen);
|
m_screens.append(screen);
|
||||||
screenAdded(screen);
|
QWindowSystemInterface::handleScreenAdded(screen);
|
||||||
}
|
}
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -107,9 +107,6 @@ public:
|
|||||||
|
|
||||||
static QWindowsIntegration *instance() { return m_instance; }
|
static QWindowsIntegration *instance() { return m_instance; }
|
||||||
|
|
||||||
inline void emitScreenAdded(QPlatformScreen *s, bool isPrimary = false) { screenAdded(s, isPrimary); }
|
|
||||||
inline void emitDestroyScreen(QPlatformScreen *s) { destroyScreen(s); }
|
|
||||||
|
|
||||||
unsigned options() const;
|
unsigned options() const;
|
||||||
|
|
||||||
void beep() const override;
|
void beep() const override;
|
||||||
|
@ -121,7 +121,7 @@ BOOL QT_WIN_CALLBACK monitorEnumCallback(HMONITOR hMonitor, HDC, LPRECT, LPARAM
|
|||||||
QWindowsScreenData data;
|
QWindowsScreenData data;
|
||||||
if (monitorData(hMonitor, &data)) {
|
if (monitorData(hMonitor, &data)) {
|
||||||
WindowsScreenDataList *result = reinterpret_cast<WindowsScreenDataList *>(p);
|
WindowsScreenDataList *result = reinterpret_cast<WindowsScreenDataList *>(p);
|
||||||
// QPlatformIntegration::screenAdded() documentation specifies that first
|
// QWindowSystemInterface::handleScreenAdded() documentation specifies that first
|
||||||
// added screen will be the primary screen, so order accordingly.
|
// added screen will be the primary screen, so order accordingly.
|
||||||
// Note that the side effect of this policy is that there is no way to change primary
|
// Note that the side effect of this policy is that there is no way to change primary
|
||||||
// screen reported by Qt, unless we want to delete all existing screens and add them
|
// screen reported by Qt, unless we want to delete all existing screens and add them
|
||||||
@ -521,7 +521,7 @@ void QWindowsScreenManager::removeScreen(int index)
|
|||||||
if (movedWindowCount)
|
if (movedWindowCount)
|
||||||
QWindowSystemInterface::flushWindowSystemEvents();
|
QWindowSystemInterface::flushWindowSystemEvents();
|
||||||
}
|
}
|
||||||
QWindowsIntegration::instance()->emitDestroyScreen(m_screens.takeAt(index));
|
QWindowSystemInterface::handleScreenRemoved(m_screens.takeAt(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -541,7 +541,7 @@ bool QWindowsScreenManager::handleScreenChanges()
|
|||||||
} else {
|
} else {
|
||||||
QWindowsScreen *newScreen = new QWindowsScreen(newData);
|
QWindowsScreen *newScreen = new QWindowsScreen(newData);
|
||||||
m_screens.push_back(newScreen);
|
m_screens.push_back(newScreen);
|
||||||
QWindowsIntegration::instance()->emitScreenAdded(newScreen,
|
QWindowSystemInterface::handleScreenAdded(newScreen,
|
||||||
newData.flags & QWindowsScreenData::PrimaryScreen);
|
newData.flags & QWindowsScreenData::PrimaryScreen);
|
||||||
qCDebug(lcQpaWindows) << "New Monitor: " << newData;
|
qCDebug(lcQpaWindows) << "New Monitor: " << newData;
|
||||||
} // exists
|
} // exists
|
||||||
@ -561,7 +561,7 @@ void QWindowsScreenManager::clearScreens()
|
|||||||
{
|
{
|
||||||
// Delete screens in reverse order to avoid crash in case of multiple screens
|
// Delete screens in reverse order to avoid crash in case of multiple screens
|
||||||
while (!m_screens.isEmpty())
|
while (!m_screens.isEmpty())
|
||||||
QWindowsIntegration::instance()->emitDestroyScreen(m_screens.takeLast());
|
QWindowSystemInterface::handleScreenRemoved(m_screens.takeLast());
|
||||||
}
|
}
|
||||||
|
|
||||||
const QWindowsScreen *QWindowsScreenManager::screenAtDp(const QPoint &p) const
|
const QWindowsScreen *QWindowsScreenManager::screenAtDp(const QPoint &p) const
|
||||||
|
@ -1759,15 +1759,12 @@ void QWindowsWindow::checkForScreenChanged()
|
|||||||
|
|
||||||
QPlatformScreen *currentScreen = screen();
|
QPlatformScreen *currentScreen = screen();
|
||||||
const auto &screenManager = QWindowsContext::instance()->screenManager();
|
const auto &screenManager = QWindowsContext::instance()->screenManager();
|
||||||
// QTBUG-62971: When dragging a window by its border, detect by mouse position
|
const QWindowsScreen *newScreen = screenManager.screenForHwnd(m_data.hwnd);
|
||||||
// to prevent it from oscillating between screens when it resizes
|
|
||||||
const QWindowsScreen *newScreen = testFlag(ResizeMoveActive)
|
|
||||||
? screenManager.screenAtDp(QWindowsCursor::mousePosition())
|
|
||||||
: screenManager.screenForHwnd(m_data.hwnd);
|
|
||||||
if (newScreen != nullptr && newScreen != currentScreen) {
|
if (newScreen != nullptr && newScreen != currentScreen) {
|
||||||
qCDebug(lcQpaWindows).noquote().nospace() << __FUNCTION__
|
qCDebug(lcQpaWindows).noquote().nospace() << __FUNCTION__
|
||||||
<< ' ' << window() << " \"" << currentScreen->name()
|
<< ' ' << window() << " \"" << currentScreen->name()
|
||||||
<< "\"->\"" << newScreen->name() << '"';
|
<< "\"->\"" << newScreen->name() << '"';
|
||||||
|
setFlag(SynchronousGeometryChangeEvent);
|
||||||
QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->screen());
|
QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->screen());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1786,11 +1783,14 @@ void QWindowsWindow::handleGeometryChange()
|
|||||||
fireExpose(QRect(QPoint(0, 0), m_data.geometry.size()), true);
|
fireExpose(QRect(QPoint(0, 0), m_data.geometry.size()), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const bool wasSync = testFlag(SynchronousGeometryChangeEvent);
|
||||||
checkForScreenChanged();
|
checkForScreenChanged();
|
||||||
|
|
||||||
if (testFlag(SynchronousGeometryChangeEvent))
|
if (testFlag(SynchronousGeometryChangeEvent))
|
||||||
QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
|
QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
|
||||||
|
|
||||||
|
if (!wasSync)
|
||||||
|
clearFlag(SynchronousGeometryChangeEvent);
|
||||||
qCDebug(lcQpaEvents) << __FUNCTION__ << this << window() << m_data.geometry;
|
qCDebug(lcQpaEvents) << __FUNCTION__ << this << window() << m_data.geometry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,7 +133,7 @@ QWinRTIntegration::QWinRTIntegration() : d_ptr(new QWinRTIntegrationPrivate)
|
|||||||
});
|
});
|
||||||
d->inputContext.reset(new QWinRTInputContext(d->mainScreen));
|
d->inputContext.reset(new QWinRTInputContext(d->mainScreen));
|
||||||
|
|
||||||
screenAdded(d->mainScreen);
|
QWindowSystemInterface::handleScreenAdded(d->mainScreen);
|
||||||
d->platformServices = new QWinRTServices;
|
d->platformServices = new QWinRTServices;
|
||||||
d->clipboard = new QWinRTClipboard;
|
d->clipboard = new QWinRTClipboard;
|
||||||
#if QT_CONFIG(accessibility)
|
#if QT_CONFIG(accessibility)
|
||||||
@ -154,7 +154,7 @@ QWinRTIntegration::~QWinRTIntegration()
|
|||||||
Q_ASSERT_SUCCEEDED(hr);
|
Q_ASSERT_SUCCEEDED(hr);
|
||||||
}
|
}
|
||||||
|
|
||||||
destroyScreen(d->mainScreen);
|
QWindowSystemInterface::handleScreenRemoved(d->mainScreen);
|
||||||
Windows::Foundation::Uninitialize();
|
Windows::Foundation::Uninitialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -652,6 +652,12 @@ static const char *qglx_threadedgl_blacklist_renderer[] = {
|
|||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const char *qglx_threadedgl_blacklist_vendor[] = {
|
||||||
|
"llvmpipe", // QTCREATORBUG-10666
|
||||||
|
"nouveau", // https://bugs.freedesktop.org/show_bug.cgi?id=91632
|
||||||
|
nullptr
|
||||||
|
};
|
||||||
|
|
||||||
void QGLXContext::queryDummyContext()
|
void QGLXContext::queryDummyContext()
|
||||||
{
|
{
|
||||||
if (m_queriedDummyContext)
|
if (m_queriedDummyContext)
|
||||||
@ -710,6 +716,18 @@ void QGLXContext::queryDummyContext()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (const char *vendor = (const char *) glGetString(GL_VENDOR)) {
|
||||||
|
for (int i = 0; qglx_threadedgl_blacklist_vendor[i]; ++i) {
|
||||||
|
if (strstr(vendor, qglx_threadedgl_blacklist_vendor[i]) != 0) {
|
||||||
|
qCDebug(lcQpaGl).nospace() << "Multithreaded OpenGL disabled: "
|
||||||
|
"blacklisted vendor \""
|
||||||
|
<< qglx_threadedgl_blacklist_vendor[i]
|
||||||
|
<< "\"";
|
||||||
|
m_supportsThreading = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (glxvendor && m_supportsThreading) {
|
if (glxvendor && m_supportsThreading) {
|
||||||
// Blacklist Mesa drivers due to QTCREATORBUG-10875 (crash in creator),
|
// Blacklist Mesa drivers due to QTCREATORBUG-10875 (crash in creator),
|
||||||
|
@ -152,10 +152,9 @@ QXcbConnection::~QXcbConnection()
|
|||||||
if (m_eventQueue)
|
if (m_eventQueue)
|
||||||
delete m_eventQueue;
|
delete m_eventQueue;
|
||||||
|
|
||||||
QXcbIntegration *integration = QXcbIntegration::instance();
|
|
||||||
// Delete screens in reverse order to avoid crash in case of multiple screens
|
// Delete screens in reverse order to avoid crash in case of multiple screens
|
||||||
while (!m_screens.isEmpty())
|
while (!m_screens.isEmpty())
|
||||||
integration->destroyScreen(m_screens.takeLast());
|
QWindowSystemInterface::handleScreenRemoved(m_screens.takeLast());
|
||||||
|
|
||||||
while (!m_virtualDesktops.isEmpty())
|
while (!m_virtualDesktops.isEmpty())
|
||||||
delete m_virtualDesktops.takeLast();
|
delete m_virtualDesktops.takeLast();
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
#define QXCBBASICCONNECTION_H
|
#define QXCBBASICCONNECTION_H
|
||||||
|
|
||||||
#include "qxcbatom.h"
|
#include "qxcbatom.h"
|
||||||
|
#include "qxcbexport.h"
|
||||||
|
|
||||||
#include <QtCore/QPair>
|
#include <QtCore/QPair>
|
||||||
#include <QtCore/QObject>
|
#include <QtCore/QObject>
|
||||||
@ -55,7 +56,7 @@ QT_BEGIN_NAMESPACE
|
|||||||
|
|
||||||
Q_DECLARE_LOGGING_CATEGORY(lcQpaXcb)
|
Q_DECLARE_LOGGING_CATEGORY(lcQpaXcb)
|
||||||
|
|
||||||
class QXcbBasicConnection : public QObject
|
class Q_XCB_EXPORT QXcbBasicConnection : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
@ -44,6 +44,8 @@
|
|||||||
#include <QtCore/QString>
|
#include <QtCore/QString>
|
||||||
#include <QtCore/QList>
|
#include <QtCore/QList>
|
||||||
|
|
||||||
|
#include <qpa/qwindowsysteminterface.h>
|
||||||
|
|
||||||
#include <xcb/xinerama.h>
|
#include <xcb/xinerama.h>
|
||||||
|
|
||||||
void QXcbConnection::xrandrSelectEvents()
|
void QXcbConnection::xrandrSelectEvents()
|
||||||
@ -211,7 +213,7 @@ void QXcbConnection::updateScreen(QXcbScreen *screen, const xcb_randr_output_cha
|
|||||||
m_screens.swapItemsAt(0, idx);
|
m_screens.swapItemsAt(0, idx);
|
||||||
}
|
}
|
||||||
screen->virtualDesktop()->setPrimaryScreen(screen);
|
screen->virtualDesktop()->setPrimaryScreen(screen);
|
||||||
QXcbIntegration::instance()->setPrimaryScreen(screen);
|
QWindowSystemInterface::handlePrimaryScreenChanged(screen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -234,7 +236,7 @@ QXcbScreen *QXcbConnection::createScreen(QXcbVirtualDesktop *virtualDesktop,
|
|||||||
m_screens.append(screen);
|
m_screens.append(screen);
|
||||||
}
|
}
|
||||||
virtualDesktop->addScreen(screen);
|
virtualDesktop->addScreen(screen);
|
||||||
QXcbIntegration::instance()->screenAdded(screen, screen->isPrimary());
|
QWindowSystemInterface::handleScreenAdded(screen, screen->isPrimary());
|
||||||
|
|
||||||
return screen;
|
return screen;
|
||||||
}
|
}
|
||||||
@ -261,10 +263,10 @@ void QXcbConnection::destroyScreen(QXcbScreen *screen)
|
|||||||
const int idx = m_screens.indexOf(newPrimary);
|
const int idx = m_screens.indexOf(newPrimary);
|
||||||
if (idx > 0)
|
if (idx > 0)
|
||||||
m_screens.swapItemsAt(0, idx);
|
m_screens.swapItemsAt(0, idx);
|
||||||
QXcbIntegration::instance()->setPrimaryScreen(newPrimary);
|
QWindowSystemInterface::handlePrimaryScreenChanged(newPrimary);
|
||||||
}
|
}
|
||||||
|
|
||||||
QXcbIntegration::instance()->destroyScreen(screen);
|
QWindowSystemInterface::handleScreenRemoved(screen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -406,7 +408,7 @@ void QXcbConnection::initializeScreens()
|
|||||||
// Push the screens to QGuiApplication
|
// Push the screens to QGuiApplication
|
||||||
for (QXcbScreen *screen : qAsConst(m_screens)) {
|
for (QXcbScreen *screen : qAsConst(m_screens)) {
|
||||||
qCDebug(lcQpaScreen) << "adding" << screen << "(Primary:" << screen->isPrimary() << ")";
|
qCDebug(lcQpaScreen) << "adding" << screen << "(Primary:" << screen->isPrimary() << ")";
|
||||||
QXcbIntegration::instance()->screenAdded(screen, screen->isPrimary());
|
QWindowSystemInterface::handleScreenAdded(screen, screen->isPrimary());
|
||||||
}
|
}
|
||||||
|
|
||||||
qCDebug(lcQpaScreen) << "primary output is" << qAsConst(m_screens).first()->name();
|
qCDebug(lcQpaScreen) << "primary output is" << qAsConst(m_screens).first()->name();
|
||||||
|
@ -137,8 +137,6 @@ private:
|
|||||||
|
|
||||||
QScopedPointer<QPlatformServices> m_services;
|
QScopedPointer<QPlatformServices> m_services;
|
||||||
|
|
||||||
friend class QXcbConnection; // access QPlatformIntegration::screenAdded()
|
|
||||||
|
|
||||||
mutable QByteArray m_wmClass;
|
mutable QByteArray m_wmClass;
|
||||||
const char *m_instanceName;
|
const char *m_instanceName;
|
||||||
bool m_canGrab;
|
bool m_canGrab;
|
||||||
|
@ -412,12 +412,15 @@ void *QXcbNativeInterface::atspiBus()
|
|||||||
auto reply = Q_XCB_REPLY(xcb_get_property, defaultConnection->xcb_connection(),
|
auto reply = Q_XCB_REPLY(xcb_get_property, defaultConnection->xcb_connection(),
|
||||||
false, defaultConnection->rootWindow(),
|
false, defaultConnection->rootWindow(),
|
||||||
atspiBusAtom, XCB_ATOM_STRING, 0, 128);
|
atspiBusAtom, XCB_ATOM_STRING, 0, 128);
|
||||||
Q_ASSERT(!reply->bytes_after);
|
if (!reply)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
char *data = (char *)xcb_get_property_value(reply.get());
|
char *data = (char *)xcb_get_property_value(reply.get());
|
||||||
int length = xcb_get_property_value_length(reply.get());
|
int length = xcb_get_property_value_length(reply.get());
|
||||||
return new QByteArray(data, length);
|
return new QByteArray(data, length);
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QXcbNativeInterface::setAppTime(QScreen* screen, xcb_timestamp_t time)
|
void QXcbNativeInterface::setAppTime(QScreen* screen, xcb_timestamp_t time)
|
||||||
|
@ -900,7 +900,7 @@ bool readInputFile(Options *options)
|
|||||||
options->extraPlugins = extraPlugins.toString().split(QLatin1Char(','));
|
options->extraPlugins = extraPlugins.toString().split(QLatin1Char(','));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
if (!options->auxMode) {
|
||||||
const QJsonValue stdcppPath = jsonObject.value(QStringLiteral("stdcpp-path"));
|
const QJsonValue stdcppPath = jsonObject.value(QStringLiteral("stdcpp-path"));
|
||||||
if (stdcppPath.isUndefined()) {
|
if (stdcppPath.isUndefined()) {
|
||||||
fprintf(stderr, "No stdcpp-path defined in json file.\n");
|
fprintf(stderr, "No stdcpp-path defined in json file.\n");
|
||||||
|
@ -143,11 +143,6 @@ Qt::GestureType QGestureManager::registerGestureRecognizer(QGestureRecognizer *r
|
|||||||
void QGestureManager::unregisterGestureRecognizer(Qt::GestureType type)
|
void QGestureManager::unregisterGestureRecognizer(Qt::GestureType type)
|
||||||
{
|
{
|
||||||
QList<QGestureRecognizer *> list = m_recognizers.values(type);
|
QList<QGestureRecognizer *> list = m_recognizers.values(type);
|
||||||
while (QGestureRecognizer *recognizer = m_recognizers.take(type)) {
|
|
||||||
// ensuring an entry exists causes the recognizer to be deleted on destruction of the manager
|
|
||||||
auto &gestures = m_obsoleteGestures[recognizer];
|
|
||||||
Q_UNUSED(gestures);
|
|
||||||
}
|
|
||||||
foreach (QGesture *g, m_gestureToRecognizer.keys()) {
|
foreach (QGesture *g, m_gestureToRecognizer.keys()) {
|
||||||
QGestureRecognizer *recognizer = m_gestureToRecognizer.value(g);
|
QGestureRecognizer *recognizer = m_gestureToRecognizer.value(g);
|
||||||
if (list.contains(recognizer)) {
|
if (list.contains(recognizer)) {
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
|
|
||||||
#include "private/qgesture_p.h"
|
#include "private/qgesture_p.h"
|
||||||
#include "private/qgesturemanager_p.h"
|
#include "private/qgesturemanager_p.h"
|
||||||
|
#include "private/qapplication_p.h"
|
||||||
|
|
||||||
#ifndef QT_NO_GESTURES
|
#ifndef QT_NO_GESTURES
|
||||||
|
|
||||||
@ -231,6 +232,11 @@ Qt::GestureType QGestureRecognizer::registerRecognizer(QGestureRecognizer *recog
|
|||||||
*/
|
*/
|
||||||
void QGestureRecognizer::unregisterRecognizer(Qt::GestureType type)
|
void QGestureRecognizer::unregisterRecognizer(Qt::GestureType type)
|
||||||
{
|
{
|
||||||
|
auto qAppPriv = QApplicationPrivate::instance();
|
||||||
|
if (!qAppPriv)
|
||||||
|
return;
|
||||||
|
if (!qAppPriv->gestureManager)
|
||||||
|
return;
|
||||||
QGestureManager::instance()->unregisterGestureRecognizer(type);
|
QGestureManager::instance()->unregisterGestureRecognizer(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1971,8 +1971,8 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment,
|
|||||||
|
|
||||||
\value SH_Widget_Animate Deprecated. Use \l{SH_Widget_Animation_Duration} instead.
|
\value SH_Widget_Animate Deprecated. Use \l{SH_Widget_Animation_Duration} instead.
|
||||||
|
|
||||||
\value SH_Splitter_OpaqueResize Determines if resizing is opaque
|
\value SH_Splitter_OpaqueResize Determines if widgets are resized dynamically (opaquely) while
|
||||||
This enum value has been introduced in Qt 5.2
|
interactively moving the splitter. This enum value was introduced in Qt 5.2.
|
||||||
|
|
||||||
\value SH_TabBar_ChangeCurrentDelay Determines the delay before the current
|
\value SH_TabBar_ChangeCurrentDelay Determines the delay before the current
|
||||||
tab is changed while dragging over the tabbar, in milliseconds. This
|
tab is changed while dragging over the tabbar, in milliseconds. This
|
||||||
|
@ -289,8 +289,7 @@ void QSplashScreen::setPixmap(const QPixmap &pixmap)
|
|||||||
// 1) If a QDesktopScreenWidget is found in the parent hierarchy, use that (see docs on
|
// 1) If a QDesktopScreenWidget is found in the parent hierarchy, use that (see docs on
|
||||||
// QSplashScreen(QWidget *, QPixmap).
|
// QSplashScreen(QWidget *, QPixmap).
|
||||||
// 2) If a widget with associated QWindow is found, use that
|
// 2) If a widget with associated QWindow is found, use that
|
||||||
// 3) When nothing can be found, do not position the widget, allowing for
|
// 3) When nothing can be found, try to center it over the cursor
|
||||||
// QPlatformWindow::initialGeometry() to center it over the cursor
|
|
||||||
|
|
||||||
static inline int screenNumberOf(const QDesktopScreenWidget *dsw)
|
static inline int screenNumberOf(const QDesktopScreenWidget *dsw)
|
||||||
{
|
{
|
||||||
@ -307,7 +306,15 @@ const QScreen *QSplashScreenPrivate::screenFor(const QWidget *w)
|
|||||||
if (QWindow *window = p->windowHandle())
|
if (QWindow *window = p->windowHandle())
|
||||||
return window->screen();
|
return window->screen();
|
||||||
}
|
}
|
||||||
return nullptr;
|
#if QT_CONFIG(cursor)
|
||||||
|
// Note: We could rely on QPlatformWindow::initialGeometry() to center it
|
||||||
|
// over the cursor, but not all platforms (namely Android) use that.
|
||||||
|
if (QGuiApplication::screens().size() > 1) {
|
||||||
|
if (auto screenAtCursor = QGuiApplication::screenAt(QCursor::pos()))
|
||||||
|
return screenAtCursor;
|
||||||
|
}
|
||||||
|
#endif // cursor
|
||||||
|
return QGuiApplication::primaryScreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QSplashScreenPrivate::setPixmap(const QPixmap &p, const QScreen *screen)
|
void QSplashScreenPrivate::setPixmap(const QPixmap &p, const QScreen *screen)
|
||||||
|
@ -161,11 +161,10 @@ Qt::Orientation QSplitterHandle::orientation() const
|
|||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Returns \c true if widgets are resized dynamically (opaquely), otherwise
|
Returns \c true if widgets are resized dynamically (opaquely) while interactively moving the
|
||||||
returns \c false. This value is controlled by the QSplitter.
|
splitter. Otherwise returns \c false. This value is controlled by the QSplitter.
|
||||||
|
|
||||||
\sa QSplitter::opaqueResize()
|
\sa QSplitter::opaqueResize()
|
||||||
|
|
||||||
*/
|
*/
|
||||||
bool QSplitterHandle::opaqueResize() const
|
bool QSplitterHandle::opaqueResize() const
|
||||||
{
|
{
|
||||||
@ -1483,7 +1482,8 @@ int QSplitter::closestLegalPosition(int pos, int index)
|
|||||||
|
|
||||||
/*!
|
/*!
|
||||||
\property QSplitter::opaqueResize
|
\property QSplitter::opaqueResize
|
||||||
\brief whether resizing is opaque
|
Returns \c true if widgets are resized dynamically (opaquely) while interactively moving the
|
||||||
|
splitter. Otherwise returns \c false.
|
||||||
|
|
||||||
The default resize behavior is style dependent (determined by the
|
The default resize behavior is style dependent (determined by the
|
||||||
SH_Splitter_OpaqueResize style hint). However, you can override it
|
SH_Splitter_OpaqueResize style hint). However, you can override it
|
||||||
|
5
tests/auto/corelib/kernel/qtimer/BLACKLIST
Normal file
5
tests/auto/corelib/kernel/qtimer/BLACKLIST
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
[remainingTime]
|
||||||
|
windows
|
||||||
|
osx
|
||||||
|
[basic_chrono]
|
||||||
|
osx
|
@ -230,6 +230,8 @@ private slots:
|
|||||||
|
|
||||||
void convertColorTable();
|
void convertColorTable();
|
||||||
|
|
||||||
|
void wideImage();
|
||||||
|
|
||||||
#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
|
#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
|
||||||
void toWinHBITMAP_data();
|
void toWinHBITMAP_data();
|
||||||
void toWinHBITMAP();
|
void toWinHBITMAP();
|
||||||
@ -3559,6 +3561,24 @@ void tst_QImage::convertColorTable()
|
|||||||
QCOMPARE(rgb32.pixel(0,0), 0xffffffff);
|
QCOMPARE(rgb32.pixel(0,0), 0xffffffff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_QImage::wideImage()
|
||||||
|
{
|
||||||
|
// QTBUG-73731 and QTBUG-73732
|
||||||
|
QImage i(538994187, 2, QImage::Format_ARGB32);
|
||||||
|
QImage i2(32, 32, QImage::Format_ARGB32);
|
||||||
|
i2.fill(Qt::white);
|
||||||
|
|
||||||
|
// Test that it doesn't crash:
|
||||||
|
QPainter painter(&i);
|
||||||
|
// With the composition mode is SourceOver out it's an invalid write
|
||||||
|
// With the composition mode is Source it's an invalid read
|
||||||
|
painter.drawImage(0, 0, i2);
|
||||||
|
painter.setCompositionMode(QPainter::CompositionMode_Source);
|
||||||
|
painter.drawImage(0, 0, i2);
|
||||||
|
|
||||||
|
// Qt6: Test that it actually works on 64bit architectures.
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
|
#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
Q_GUI_EXPORT HBITMAP qt_imageToWinHBITMAP(const QImage &p, int hbitmapFormat = 0);
|
Q_GUI_EXPORT HBITMAP qt_imageToWinHBITMAP(const QImage &p, int hbitmapFormat = 0);
|
||||||
|
@ -4075,6 +4075,8 @@ void tst_QGraphicsView::update()
|
|||||||
QTRY_COMPARE(view.lastUpdateRegions.at(0), QRegion(updateRect) & viewportRect);
|
QTRY_COMPARE(view.lastUpdateRegions.at(0), QRegion(updateRect) & viewportRect);
|
||||||
}
|
}
|
||||||
QTRY_VERIFY(!viewPrivate->fullUpdatePending);
|
QTRY_VERIFY(!viewPrivate->fullUpdatePending);
|
||||||
|
#else
|
||||||
|
Q_UNUSED(updateRect);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,6 +126,10 @@ void MainWindow::aboutDialog()
|
|||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
#if QT_VERSION >= 0x050600
|
||||||
|
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||||
|
#endif
|
||||||
|
|
||||||
for (int a = 1; a < argc; ++a) {
|
for (int a = 1; a < argc; ++a) {
|
||||||
if (!qstrcmp(argv[a], "-n")) {
|
if (!qstrcmp(argv[a], "-n")) {
|
||||||
qDebug("AA_DontUseNativeDialogs");
|
qDebug("AA_DontUseNativeDialogs");
|
||||||
|
@ -798,6 +798,9 @@ static const char *property_string =
|
|||||||
" signed short mirrorDiff : 16;\n"
|
" signed short mirrorDiff : 16;\n"
|
||||||
" ushort lowerCaseSpecial : 1;\n"
|
" ushort lowerCaseSpecial : 1;\n"
|
||||||
" signed short lowerCaseDiff : 15;\n"
|
" signed short lowerCaseDiff : 15;\n"
|
||||||
|
"#ifdef Q_OS_WASM\n"
|
||||||
|
" unsigned char : 0; //wasm 64 packing trick\n"
|
||||||
|
"#endif\n"
|
||||||
" ushort upperCaseSpecial : 1;\n"
|
" ushort upperCaseSpecial : 1;\n"
|
||||||
" signed short upperCaseDiff : 15;\n"
|
" signed short upperCaseDiff : 15;\n"
|
||||||
" ushort titleCaseSpecial : 1;\n"
|
" ushort titleCaseSpecial : 1;\n"
|
||||||
@ -806,6 +809,9 @@ static const char *property_string =
|
|||||||
" signed short caseFoldDiff : 15;\n"
|
" signed short caseFoldDiff : 15;\n"
|
||||||
" ushort unicodeVersion : 8; /* 5 used */\n"
|
" ushort unicodeVersion : 8; /* 5 used */\n"
|
||||||
" ushort nfQuickCheck : 8;\n" // could be narrowed
|
" ushort nfQuickCheck : 8;\n" // could be narrowed
|
||||||
|
"#ifdef Q_OS_WASM\n"
|
||||||
|
" unsigned char : 0; //wasm 64 packing trick\n"
|
||||||
|
"#endif\n"
|
||||||
" ushort graphemeBreakClass : 5; /* 5 used */\n"
|
" ushort graphemeBreakClass : 5; /* 5 used */\n"
|
||||||
" ushort wordBreakClass : 5; /* 5 used */\n"
|
" ushort wordBreakClass : 5; /* 5 used */\n"
|
||||||
" ushort sentenceBreakClass : 8; /* 4 used */\n"
|
" ushort sentenceBreakClass : 8; /* 4 used */\n"
|
||||||
@ -2470,10 +2476,6 @@ static QByteArray createPropertyInfo()
|
|||||||
out += ", ";
|
out += ", ";
|
||||||
out += QByteArray::number( p.lowerCaseDiff );
|
out += QByteArray::number( p.lowerCaseDiff );
|
||||||
out += ", ";
|
out += ", ";
|
||||||
out += "#ifdef Q_OS_WASM \n";
|
|
||||||
// " unsigned char : 0; //wasm 64 packing trick QTBUG-65259\n"
|
|
||||||
out += "#endif \n";
|
|
||||||
out += ", ";
|
|
||||||
// " ushort upperCaseSpecial : 1;\n"
|
// " ushort upperCaseSpecial : 1;\n"
|
||||||
// " signed short upperCaseDiff : 15;\n"
|
// " signed short upperCaseDiff : 15;\n"
|
||||||
out += QByteArray::number( p.upperCaseSpecial );
|
out += QByteArray::number( p.upperCaseSpecial );
|
||||||
@ -2498,10 +2500,6 @@ static QByteArray createPropertyInfo()
|
|||||||
// " ushort nfQuickCheck : 8;\n"
|
// " ushort nfQuickCheck : 8;\n"
|
||||||
out += QByteArray::number( p.nfQuickCheck );
|
out += QByteArray::number( p.nfQuickCheck );
|
||||||
out += ", ";
|
out += ", ";
|
||||||
out += "#ifdef Q_OS_WASM \n";
|
|
||||||
// " unsigned char : 0; //wasm 64 packing trick QTBUG-65259\n"
|
|
||||||
out += "#endif \n";
|
|
||||||
out += ", ";
|
|
||||||
// " ushort graphemeBreakClass : 5; /* 5 used */\n"
|
// " ushort graphemeBreakClass : 5; /* 5 used */\n"
|
||||||
// " ushort wordBreakClass : 5; /* 5 used */\n"
|
// " ushort wordBreakClass : 5; /* 5 used */\n"
|
||||||
// " ushort sentenceBreakClass : 8; /* 4 used */\n"
|
// " ushort sentenceBreakClass : 8; /* 4 used */\n"
|
||||||
|
Loading…
Reference in New Issue
Block a user