mirror of
https://github.com/crystalidea/qt-build-tools.git
synced 2024-11-23 03:10:06 +08:00
5.15.2: original
This commit is contained in:
parent
d0a6ada2ae
commit
86d5454581
Binary file not shown.
@ -1,278 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
**
|
|
||||||
** Copyright (C) 2016 The Qt Company Ltd.
|
|
||||||
** Contact: https://www.qt.io/licensing/
|
|
||||||
**
|
|
||||||
** This file is part of the QtGui module 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 "qtextimagehandler_p.h"
|
|
||||||
|
|
||||||
#include <qguiapplication.h>
|
|
||||||
#include <qtextformat.h>
|
|
||||||
#include <qpainter.h>
|
|
||||||
#include <qdebug.h>
|
|
||||||
#include <qfile.h>
|
|
||||||
#include <private/qtextengine_p.h>
|
|
||||||
#include <qpalette.h>
|
|
||||||
#include <qthread.h>
|
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
|
||||||
|
|
||||||
extern QString qt_findAtNxFile(const QString &baseFileName, qreal targetDevicePixelRatio,
|
|
||||||
qreal *sourceDevicePixelRatio);
|
|
||||||
static QString resolveFileName(QString fileName, QUrl *url, qreal targetDevicePixelRatio,
|
|
||||||
qreal *sourceDevicePixelRatio)
|
|
||||||
{
|
|
||||||
// We might use the fileName for loading if url loading fails
|
|
||||||
// try to make sure it is a valid file path.
|
|
||||||
// Also, QFile{Info}::exists works only on filepaths (not urls)
|
|
||||||
|
|
||||||
if (url->isValid()) {
|
|
||||||
if (url->scheme() == QLatin1String("qrc")) {
|
|
||||||
fileName = fileName.right(fileName.length() - 3);
|
|
||||||
}
|
|
||||||
else if (url->scheme() == QLatin1String("file")) {
|
|
||||||
fileName = url->toLocalFile();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (targetDevicePixelRatio <= 1.0)
|
|
||||||
return fileName;
|
|
||||||
|
|
||||||
// try to find a Nx version
|
|
||||||
return qt_findAtNxFile(fileName, targetDevicePixelRatio, sourceDevicePixelRatio);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static QPixmap getPixmap(QTextDocument *doc, const QTextImageFormat &format, const qreal devicePixelRatio = 1.0)
|
|
||||||
{
|
|
||||||
QPixmap pm;
|
|
||||||
|
|
||||||
QString name = format.name();
|
|
||||||
if (name.startsWith(QLatin1String(":/"))) // auto-detect resources and convert them to url
|
|
||||||
name.prepend(QLatin1String("qrc"));
|
|
||||||
QUrl url = QUrl(name);
|
|
||||||
qreal sourcePixelRatio = 1.0;
|
|
||||||
name = resolveFileName(name, &url, devicePixelRatio, &sourcePixelRatio);
|
|
||||||
|
|
||||||
if (name.contains(QLatin1String("@2x")))
|
|
||||||
url = QUrl(name); // url must be updated! (QTBUG-52697)
|
|
||||||
|
|
||||||
const QVariant data = doc->resource(QTextDocument::ImageResource, url);
|
|
||||||
if (data.userType() == QMetaType::QPixmap || data.userType() == QMetaType::QImage) {
|
|
||||||
pm = qvariant_cast<QPixmap>(data);
|
|
||||||
} else if (data.userType() == QMetaType::QByteArray) {
|
|
||||||
pm.loadFromData(data.toByteArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pm.isNull()) {
|
|
||||||
#if 0
|
|
||||||
QString context;
|
|
||||||
// ### Qt5
|
|
||||||
QTextBrowser *browser = qobject_cast<QTextBrowser *>(doc->parent());
|
|
||||||
if (browser)
|
|
||||||
context = browser->source().toString();
|
|
||||||
#endif
|
|
||||||
// try direct loading
|
|
||||||
QImage img;
|
|
||||||
if (name.isEmpty() || !img.load(name))
|
|
||||||
return QPixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/file-16.png"));
|
|
||||||
|
|
||||||
pm = QPixmap::fromImage(img);
|
|
||||||
doc->addResource(QTextDocument::ImageResource, url, pm);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (name.contains(QLatin1String("@2x")))
|
|
||||||
pm.setDevicePixelRatio(sourcePixelRatio);
|
|
||||||
|
|
||||||
return pm;
|
|
||||||
}
|
|
||||||
|
|
||||||
static QSize getPixmapSize(QTextDocument *doc, const QTextImageFormat &format)
|
|
||||||
{
|
|
||||||
QPixmap pm;
|
|
||||||
|
|
||||||
const bool hasWidth = format.hasProperty(QTextFormat::ImageWidth);
|
|
||||||
const int width = qRound(format.width());
|
|
||||||
const bool hasHeight = format.hasProperty(QTextFormat::ImageHeight);
|
|
||||||
const int height = qRound(format.height());
|
|
||||||
|
|
||||||
QPaintDevice *pdev = doc->documentLayout()->paintDevice();
|
|
||||||
|
|
||||||
QSize size(width, height);
|
|
||||||
if (!hasWidth || !hasHeight) {
|
|
||||||
pm = getPixmap(doc, format, pdev ? pdev->devicePixelRatioF() : 1.0);
|
|
||||||
const int pmWidth = pm.width() / pm.devicePixelRatio();
|
|
||||||
const int pmHeight = pm.height() / pm.devicePixelRatio();
|
|
||||||
|
|
||||||
if (!hasWidth) {
|
|
||||||
if (!hasHeight)
|
|
||||||
size.setWidth(pmWidth);
|
|
||||||
else
|
|
||||||
size.setWidth(qRound(height * (pmWidth / (qreal) pmHeight)));
|
|
||||||
}
|
|
||||||
if (!hasHeight) {
|
|
||||||
if (!hasWidth)
|
|
||||||
size.setHeight(pmHeight);
|
|
||||||
else
|
|
||||||
size.setHeight(qRound(width * (pmHeight / (qreal) pmWidth)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
qreal scale = 1.0;
|
|
||||||
|
|
||||||
if (pdev) {
|
|
||||||
if (pm.isNull())
|
|
||||||
pm = getPixmap(doc, format);
|
|
||||||
if (!pm.isNull())
|
|
||||||
scale = qreal(pdev->logicalDpiY()) / qreal(qt_defaultDpi());
|
|
||||||
}
|
|
||||||
size *= scale;
|
|
||||||
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
static QImage getImage(QTextDocument *doc, const QTextImageFormat &format, const qreal devicePixelRatio = 1.0)
|
|
||||||
{
|
|
||||||
QImage image;
|
|
||||||
|
|
||||||
QString name = format.name();
|
|
||||||
if (name.startsWith(QLatin1String(":/"))) // auto-detect resources
|
|
||||||
name.prepend(QLatin1String("qrc"));
|
|
||||||
QUrl url = QUrl(name);
|
|
||||||
qreal sourcePixelRatio = 1.0;
|
|
||||||
name = resolveFileName(name, &url, devicePixelRatio, &sourcePixelRatio);
|
|
||||||
|
|
||||||
if (name.contains(QLatin1String("@2x")))
|
|
||||||
url = QUrl(name); // url must be updated! (QTBUG-52697)
|
|
||||||
|
|
||||||
const QVariant data = doc->resource(QTextDocument::ImageResource, url);
|
|
||||||
if (data.userType() == QMetaType::QImage) {
|
|
||||||
image = qvariant_cast<QImage>(data);
|
|
||||||
} else if (data.userType() == QMetaType::QByteArray) {
|
|
||||||
image.loadFromData(data.toByteArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (image.isNull()) {
|
|
||||||
#if 0
|
|
||||||
QString context;
|
|
||||||
// ### Qt5
|
|
||||||
QTextBrowser *browser = qobject_cast<QTextBrowser *>(doc->parent());
|
|
||||||
if (browser)
|
|
||||||
context = browser->source().toString();
|
|
||||||
#endif
|
|
||||||
// try direct loading
|
|
||||||
|
|
||||||
if (name.isEmpty() || !image.load(name))
|
|
||||||
return QImage(QLatin1String(":/qt-project.org/styles/commonstyle/images/file-16.png"));
|
|
||||||
|
|
||||||
doc->addResource(QTextDocument::ImageResource, url, image);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sourcePixelRatio != 1.0)
|
|
||||||
image.setDevicePixelRatio(sourcePixelRatio);
|
|
||||||
|
|
||||||
return image;
|
|
||||||
}
|
|
||||||
|
|
||||||
static QSize getImageSize(QTextDocument *doc, const QTextImageFormat &format)
|
|
||||||
{
|
|
||||||
QImage image;
|
|
||||||
|
|
||||||
const bool hasWidth = format.hasProperty(QTextFormat::ImageWidth);
|
|
||||||
const int width = qRound(format.width());
|
|
||||||
const bool hasHeight = format.hasProperty(QTextFormat::ImageHeight);
|
|
||||||
const int height = qRound(format.height());
|
|
||||||
|
|
||||||
QSize size(width, height);
|
|
||||||
if (!hasWidth || !hasHeight) {
|
|
||||||
image = getImage(doc, format);
|
|
||||||
if (!hasWidth)
|
|
||||||
size.setWidth(image.width() / image.devicePixelRatio());
|
|
||||||
if (!hasHeight)
|
|
||||||
size.setHeight(image.height() / image.devicePixelRatio());
|
|
||||||
}
|
|
||||||
|
|
||||||
qreal scale = 1.0;
|
|
||||||
QPaintDevice *pdev = doc->documentLayout()->paintDevice();
|
|
||||||
if (pdev) {
|
|
||||||
if (image.isNull())
|
|
||||||
image = getImage(doc, format);
|
|
||||||
if (!image.isNull())
|
|
||||||
scale = qreal(pdev->logicalDpiY()) / qreal(qt_defaultDpi());
|
|
||||||
}
|
|
||||||
size *= scale;
|
|
||||||
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
QTextImageHandler::QTextImageHandler(QObject *parent)
|
|
||||||
: QObject(parent)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
QSizeF QTextImageHandler::intrinsicSize(QTextDocument *doc, int posInDocument, const QTextFormat &format)
|
|
||||||
{
|
|
||||||
Q_UNUSED(posInDocument)
|
|
||||||
const QTextImageFormat imageFormat = format.toImageFormat();
|
|
||||||
|
|
||||||
if (QCoreApplication::instance()->thread() != QThread::currentThread())
|
|
||||||
return getImageSize(doc, imageFormat);
|
|
||||||
return getPixmapSize(doc, imageFormat);
|
|
||||||
}
|
|
||||||
|
|
||||||
QImage QTextImageHandler::image(QTextDocument *doc, const QTextImageFormat &imageFormat)
|
|
||||||
{
|
|
||||||
Q_ASSERT(doc != nullptr);
|
|
||||||
|
|
||||||
return getImage(doc, imageFormat);
|
|
||||||
}
|
|
||||||
|
|
||||||
void QTextImageHandler::drawObject(QPainter *p, const QRectF &rect, QTextDocument *doc, int posInDocument, const QTextFormat &format)
|
|
||||||
{
|
|
||||||
Q_UNUSED(posInDocument)
|
|
||||||
const QTextImageFormat imageFormat = format.toImageFormat();
|
|
||||||
|
|
||||||
if (QCoreApplication::instance()->thread() != QThread::currentThread()) {
|
|
||||||
const QImage image = getImage(doc, imageFormat, p->device()->devicePixelRatioF());
|
|
||||||
p->drawImage(rect, image, image.rect());
|
|
||||||
} else {
|
|
||||||
const QPixmap pixmap = getPixmap(doc, imageFormat, p->device()->devicePixelRatioF());
|
|
||||||
p->drawPixmap(rect, pixmap, pixmap.rect());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
|
BIN
5.15.2/bin/7z.exe
Normal file
BIN
5.15.2/bin/7z.exe
Normal file
Binary file not shown.
@ -1,6 +1,6 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
export PATH=$PATH:/usr/local/Qt-5.15.1/bin
|
export PATH=$PATH:/usr/local/Qt-5.15.2/bin
|
||||||
|
|
||||||
cd qtbase
|
cd qtbase
|
||||||
|
|
||||||
@ -20,4 +20,4 @@ make -j 12
|
|||||||
echo maki | sudo -S sudo make install
|
echo maki | sudo -S sudo make install
|
||||||
|
|
||||||
cd /usr/local
|
cd /usr/local
|
||||||
zip -r ~/Desktop/qt5.15.1_mac.zip Qt-5.15.1/*
|
zip -r ~/Desktop/qt5.15.2_mac.zip Qt-5.15.2/*
|
23
5.15.2/compile_mac_arm.sh
Normal file
23
5.15.2/compile_mac_arm.sh
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
export PATH=$PATH:/usr/local/Qt-5.15.2/bin
|
||||||
|
|
||||||
|
cd qtbase
|
||||||
|
|
||||||
|
./configure $OPTIONS QMAKE_APPLE_DEVICE_ARCHS=arm64 -opensource -confirm-license -nomake examples -nomake tests -no-openssl -securetransport
|
||||||
|
|
||||||
|
make -j 8
|
||||||
|
echo maki | sudo -S sudo make install
|
||||||
|
|
||||||
|
cd ../qttools
|
||||||
|
qmake
|
||||||
|
make -j 8
|
||||||
|
echo maki | sudo -S sudo make install
|
||||||
|
|
||||||
|
cd ../qtmacextras
|
||||||
|
qmake
|
||||||
|
make -j 8
|
||||||
|
echo maki | sudo -S sudo make install
|
||||||
|
|
||||||
|
cd /usr/local
|
||||||
|
zip -r ~/Desktop/qt5.15.2_mac_arm.zip Qt-5.15.2/*
|
17
5.15.2/compile_mac_dev.sh
Normal file
17
5.15.2/compile_mac_dev.sh
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
export PATH=$PATH:/usr/local/Qt-5.15.2/bin
|
||||||
|
|
||||||
|
cd qtbase
|
||||||
|
|
||||||
|
./configure -developer-build -opensource -confirm-license -nomake examples -nomake tests -no-openssl -securetransport
|
||||||
|
|
||||||
|
make -j 12
|
||||||
|
|
||||||
|
cd ../qttools
|
||||||
|
qmake
|
||||||
|
make -j 12
|
||||||
|
|
||||||
|
cd ../qtmacextras
|
||||||
|
qmake
|
||||||
|
make -j 12
|
@ -38,7 +38,7 @@ QMAKE_YACCFLAGS = -d
|
|||||||
QMAKE_CFLAGS = -nologo -Zc:wchar_t
|
QMAKE_CFLAGS = -nologo -Zc:wchar_t
|
||||||
QMAKE_CFLAGS_WARN_ON = -W3
|
QMAKE_CFLAGS_WARN_ON = -W3
|
||||||
QMAKE_CFLAGS_WARN_OFF = -W0
|
QMAKE_CFLAGS_WARN_OFF = -W0
|
||||||
QMAKE_CFLAGS_RELEASE = $$QMAKE_CFLAGS_OPTIMIZE -MD -Zi
|
QMAKE_CFLAGS_RELEASE = $$QMAKE_CFLAGS_OPTIMIZE -MD
|
||||||
QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += $$QMAKE_CFLAGS_OPTIMIZE -Zi -MD
|
QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += $$QMAKE_CFLAGS_OPTIMIZE -Zi -MD
|
||||||
QMAKE_CFLAGS_DEBUG = -Zi -MDd
|
QMAKE_CFLAGS_DEBUG = -Zi -MDd
|
||||||
QMAKE_CFLAGS_YACC =
|
QMAKE_CFLAGS_YACC =
|
||||||
@ -100,7 +100,7 @@ QMAKE_EXTENSION_STATICLIB = lib
|
|||||||
|
|
||||||
QMAKE_LIBS =
|
QMAKE_LIBS =
|
||||||
QMAKE_LIBS_GUI = gdi32.lib comdlg32.lib oleaut32.lib imm32.lib winmm.lib ws2_32.lib ole32.lib uuid.lib user32.lib advapi32.lib
|
QMAKE_LIBS_GUI = gdi32.lib comdlg32.lib oleaut32.lib imm32.lib winmm.lib ws2_32.lib ole32.lib uuid.lib user32.lib advapi32.lib
|
||||||
QMAKE_LIBS_NETWORK = ws2_32.lib user32.lib gdi32.lib
|
QMAKE_LIBS_NETWORK = ws2_32.lib
|
||||||
QMAKE_LIBS_OPENGL = glu32.lib opengl32.lib gdi32.lib user32.lib
|
QMAKE_LIBS_OPENGL = glu32.lib opengl32.lib gdi32.lib user32.lib
|
||||||
QMAKE_LIBS_OPENGL_ES2 = gdi32.lib user32.lib
|
QMAKE_LIBS_OPENGL_ES2 = gdi32.lib user32.lib
|
||||||
QMAKE_LIBS_OPENGL_ES2_DEBUG = gdi32.lib user32.lib
|
QMAKE_LIBS_OPENGL_ES2_DEBUG = gdi32.lib user32.lib
|
288
5.15.2/qtbase/src/plugins/platforms/cocoa/qnsview_drawing.mm
Normal file
288
5.15.2/qtbase/src/plugins/platforms/cocoa/qnsview_drawing.mm
Normal file
@ -0,0 +1,288 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2018 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$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
// This file is included from qnsview.mm, and only used to organize the code
|
||||||
|
|
||||||
|
@implementation QNSView (Drawing)
|
||||||
|
|
||||||
|
- (void)initDrawing
|
||||||
|
{
|
||||||
|
[self updateLayerBacking];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)isOpaque
|
||||||
|
{
|
||||||
|
if (!m_platformWindow)
|
||||||
|
return true;
|
||||||
|
return m_platformWindow->isOpaque();
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)isFlipped
|
||||||
|
{
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------- Layer setup -----------------------
|
||||||
|
|
||||||
|
- (void)updateLayerBacking
|
||||||
|
{
|
||||||
|
self.wantsLayer = [self layerEnabledByMacOS]
|
||||||
|
|| [self layerExplicitlyRequested]
|
||||||
|
|| [self shouldUseMetalLayer];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)layerEnabledByMacOS
|
||||||
|
{
|
||||||
|
// AppKit has its own logic for this, but if we rely on that, our layers are created
|
||||||
|
// by AppKit at a point where we've already set up other parts of the platform plugin
|
||||||
|
// based on the presence of layers or not. Once we've rewritten these parts to support
|
||||||
|
// dynamically picking up layer enablement we can let AppKit do its thing.
|
||||||
|
return QMacVersion::buildSDK() >= QOperatingSystemVersion::MacOSMojave
|
||||||
|
&& QMacVersion::currentRuntime() >= QOperatingSystemVersion::MacOSMojave;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)layerExplicitlyRequested
|
||||||
|
{
|
||||||
|
static bool wantsLayer = [&]() {
|
||||||
|
int wantsLayer = qt_mac_resolveOption(-1, m_platformWindow->window(),
|
||||||
|
"_q_mac_wantsLayer", "QT_MAC_WANTS_LAYER");
|
||||||
|
|
||||||
|
if (wantsLayer != -1 && [self layerEnabledByMacOS]) {
|
||||||
|
qCWarning(lcQpaDrawing) << "Layer-backing cannot be explicitly controlled on 10.14 when built against the 10.14 SDK";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return wantsLayer == 1;
|
||||||
|
}();
|
||||||
|
|
||||||
|
return wantsLayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)shouldUseMetalLayer
|
||||||
|
{
|
||||||
|
// MetalSurface needs a layer, and so does VulkanSurface (via MoltenVK)
|
||||||
|
QSurface::SurfaceType surfaceType = m_platformWindow->window()->surfaceType();
|
||||||
|
return surfaceType == QWindow::MetalSurface || surfaceType == QWindow::VulkanSurface;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
This method is called by AppKit when layer-backing is requested by
|
||||||
|
setting wantsLayer too YES (via -[NSView _updateLayerBackedness]),
|
||||||
|
or in cases where AppKit itself decides that a view should be
|
||||||
|
layer-backed.
|
||||||
|
|
||||||
|
Note however that some code paths in AppKit will not go via this
|
||||||
|
method for creating the backing layer, and will instead create the
|
||||||
|
layer manually, and just call setLayer. An example of this is when
|
||||||
|
an NSOpenGLContext is attached to a view, in which case AppKit will
|
||||||
|
create a new layer in NSOpenGLContextSetLayerOnViewIfNecessary.
|
||||||
|
|
||||||
|
For this reason we leave the implementation of this override as
|
||||||
|
minimal as possible, only focusing on creating the appropriate
|
||||||
|
layer type, and then leave it up to setLayer to do the work of
|
||||||
|
making sure the layer is set up correctly.
|
||||||
|
*/
|
||||||
|
- (CALayer *)makeBackingLayer
|
||||||
|
{
|
||||||
|
if ([self shouldUseMetalLayer]) {
|
||||||
|
// Check if Metal is supported. If it isn't then it's most likely
|
||||||
|
// too late at this point and the QWindow will be non-functional,
|
||||||
|
// but we can at least print a warning.
|
||||||
|
if ([MTLCreateSystemDefaultDevice() autorelease]) {
|
||||||
|
return [CAMetalLayer layer];
|
||||||
|
} else {
|
||||||
|
qCWarning(lcQpaDrawing) << "Failed to create QWindow::MetalSurface."
|
||||||
|
<< "Metal is not supported by any of the GPUs in this system.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return [super makeBackingLayer];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
This method is called by AppKit whenever the view is asked to change
|
||||||
|
its layer, which can happen both as a result of enabling layer-backing,
|
||||||
|
or when a layer is set explicitly. The latter can happen both when a
|
||||||
|
view is layer-hosting, or when AppKit internals are switching out the
|
||||||
|
layer-backed view, as described above for makeBackingLayer.
|
||||||
|
*/
|
||||||
|
- (void)setLayer:(CALayer *)layer
|
||||||
|
{
|
||||||
|
qCDebug(lcQpaDrawing) << "Making" << self
|
||||||
|
<< (self.wantsLayer ? "layer-backed" : "layer-hosted")
|
||||||
|
<< "with" << layer << "due to being" << ([self layerExplicitlyRequested] ? "explicitly requested"
|
||||||
|
: [self shouldUseMetalLayer] ? "needed by surface type" : "enabled by macOS");
|
||||||
|
|
||||||
|
if (layer.delegate && layer.delegate != self) {
|
||||||
|
qCWarning(lcQpaDrawing) << "Layer already has delegate" << layer.delegate
|
||||||
|
<< "This delegate is responsible for all view updates for" << self;
|
||||||
|
} else {
|
||||||
|
layer.delegate = self;
|
||||||
|
}
|
||||||
|
|
||||||
|
[super setLayer:layer];
|
||||||
|
|
||||||
|
// When adding a view to a view hierarchy the backing properties will change
|
||||||
|
// which results in updating the contents scale, but in case of switching the
|
||||||
|
// layer on a view that's already in a view hierarchy we need to manually ensure
|
||||||
|
// the scale is up to date.
|
||||||
|
if (self.superview)
|
||||||
|
[self updateLayerContentsScale];
|
||||||
|
|
||||||
|
if (self.opaque && lcQpaDrawing().isDebugEnabled()) {
|
||||||
|
// If the view claims to be opaque we expect it to fill the entire
|
||||||
|
// layer with content, in which case we want to detect any areas
|
||||||
|
// where it doesn't.
|
||||||
|
layer.backgroundColor = NSColor.magentaColor.CGColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------- Layer updates -----------------------
|
||||||
|
|
||||||
|
- (NSViewLayerContentsRedrawPolicy)layerContentsRedrawPolicy
|
||||||
|
{
|
||||||
|
// We need to set this explicitly since the super implementation
|
||||||
|
// returns LayerContentsRedrawNever for custom layers like CAMetalLayer.
|
||||||
|
return NSViewLayerContentsRedrawDuringViewResize;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSViewLayerContentsPlacement)layerContentsPlacement
|
||||||
|
{
|
||||||
|
// Always place the layer at top left without any automatic scaling.
|
||||||
|
// This will highlight situations where we're missing content for the
|
||||||
|
// layer by not responding to the displayLayer: request synchronously.
|
||||||
|
// It also allows us to re-use larger layers when resizing a window down.
|
||||||
|
return NSViewLayerContentsPlacementTopLeft;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)viewDidChangeBackingProperties
|
||||||
|
{
|
||||||
|
qCDebug(lcQpaDrawing) << "Backing properties changed for" << self;
|
||||||
|
|
||||||
|
if (self.layer)
|
||||||
|
[self updateLayerContentsScale];
|
||||||
|
|
||||||
|
// Ideally we would plumb this situation through QPA in a way that lets
|
||||||
|
// clients invalidate their own caches, recreate QBackingStore, etc.
|
||||||
|
// For now we trigger an expose, and let QCocoaBackingStore deal with
|
||||||
|
// buffer invalidation internally.
|
||||||
|
[self setNeedsDisplay:YES];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)updateLayerContentsScale
|
||||||
|
{
|
||||||
|
// We expect clients to fill the layer with retina aware content,
|
||||||
|
// based on the devicePixelRatio of the QWindow, so we set the
|
||||||
|
// layer's content scale to match that. By going via devicePixelRatio
|
||||||
|
// instead of applying the NSWindow's backingScaleFactor, we also take
|
||||||
|
// into account OpenGL views with wantsBestResolutionOpenGLSurface set
|
||||||
|
// to NO. In this case the window will have a backingScaleFactor of 2,
|
||||||
|
// but the QWindow will have a devicePixelRatio of 1.
|
||||||
|
auto devicePixelRatio = m_platformWindow->devicePixelRatio();
|
||||||
|
qCDebug(lcQpaDrawing) << "Updating" << self.layer << "content scale to" << devicePixelRatio;
|
||||||
|
self.layer.contentsScale = devicePixelRatio;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
This method is called by AppKit to determine whether it should update
|
||||||
|
the contentScale of the layer to match the window backing scale.
|
||||||
|
|
||||||
|
We always return NO since we're updating the contents scale manually.
|
||||||
|
*/
|
||||||
|
- (BOOL)layer:(CALayer *)layer shouldInheritContentsScale:(CGFloat)scale fromWindow:(NSWindow *)window
|
||||||
|
{
|
||||||
|
Q_UNUSED(layer); Q_UNUSED(scale); Q_UNUSED(window);
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------- Draw callbacks -----------------------
|
||||||
|
|
||||||
|
/*
|
||||||
|
This method is called by AppKit for the non-layer case, where we are
|
||||||
|
drawing into the NSWindow's surface.
|
||||||
|
*/
|
||||||
|
- (void)drawRect:(NSRect)dirtyBoundingRect
|
||||||
|
{
|
||||||
|
Q_ASSERT_X(!self.layer, "QNSView",
|
||||||
|
"The drawRect code path should not be hit when we are layer backed");
|
||||||
|
|
||||||
|
if (!m_platformWindow)
|
||||||
|
return;
|
||||||
|
|
||||||
|
QRegion exposedRegion;
|
||||||
|
const NSRect *dirtyRects;
|
||||||
|
NSInteger numDirtyRects;
|
||||||
|
[self getRectsBeingDrawn:&dirtyRects count:&numDirtyRects];
|
||||||
|
for (int i = 0; i < numDirtyRects; ++i)
|
||||||
|
exposedRegion += QRectF::fromCGRect(dirtyRects[i]).toRect();
|
||||||
|
|
||||||
|
if (exposedRegion.isEmpty())
|
||||||
|
exposedRegion = QRectF::fromCGRect(dirtyBoundingRect).toRect();
|
||||||
|
|
||||||
|
qCDebug(lcQpaDrawing) << "[QNSView drawRect:]" << m_platformWindow->window() << exposedRegion;
|
||||||
|
m_platformWindow->handleExposeEvent(exposedRegion);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
This method is called by AppKit when we are layer-backed, where
|
||||||
|
we are drawing into the layer.
|
||||||
|
*/
|
||||||
|
- (void)displayLayer:(CALayer *)layer
|
||||||
|
{
|
||||||
|
Q_ASSERT_X(self.layer && layer == self.layer, "QNSView",
|
||||||
|
"The displayLayer code path should only be hit for our own layer");
|
||||||
|
|
||||||
|
if (!m_platformWindow)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!NSThread.isMainThread) {
|
||||||
|
// Qt is calling AppKit APIs such as -[NSOpenGLContext setView:] on secondary threads,
|
||||||
|
// which we shouldn't do. This may result in AppKit (wrongly) triggering a display on
|
||||||
|
// the thread where we made the call, so block it here and defer to the main thread.
|
||||||
|
qCWarning(lcQpaDrawing) << "Display non non-main thread! Deferring to main thread";
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{ self.needsDisplay = YES; });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
qCDebug(lcQpaDrawing) << "[QNSView displayLayer]" << m_platformWindow->window();
|
||||||
|
m_platformWindow->handleExposeEvent(QRectF::fromCGRect(self.bounds).toRect());
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
6670
5.15.2/qtbase/src/plugins/styles/mac/qmacstyle_mac.mm
Normal file
6670
5.15.2/qtbase/src/plugins/styles/mac/qmacstyle_mac.mm
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user