mirror of
https://github.com/crystalidea/qt-build-tools.git
synced 2024-11-26 04:31:39 +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
|
||||
|
||||
export PATH=$PATH:/usr/local/Qt-5.15.1/bin
|
||||
export PATH=$PATH:/usr/local/Qt-5.15.2/bin
|
||||
|
||||
cd qtbase
|
||||
|
||||
@ -20,4 +20,4 @@ make -j 12
|
||||
echo maki | sudo -S sudo make install
|
||||
|
||||
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_WARN_ON = -W3
|
||||
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_DEBUG = -Zi -MDd
|
||||
QMAKE_CFLAGS_YACC =
|
||||
@ -100,7 +100,7 @@ QMAKE_EXTENSION_STATICLIB = lib
|
||||
|
||||
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_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_ES2 = 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