macOS: Pick up QWizard background from keyboard assistant via NSBundle

As of macOS 10.14 the keyboard assistant background is shipped as part
of the compiled asset catalog of the app, so looking it up via a URL
will fail.

Instead we look it up via NSBundle's dedicated image lookup function,
which handles both cases.

The logic has also been moved to qwizard.cpp, since the additional
plumbing via QPlatformNativeInterface was unnecessary.

The keyboard assistant itself no longer shows the background image
as of macOS 12, so we might consider doing the same, but the design
of the assistant has also changed significantly, so as long as our
QWizard layout looks like the old keyboard assistant we keep the
background as well.

Change-Id: I7d42dd79b285f3518837458864bca6bc353b3b6d
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
(cherry picked from commit c26c91b2088a05bbe1ed3b529a4b0fc0ea9d3a92)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Tor Arne Vestbø 2023-02-15 12:36:20 +01:00 committed by Qt Cherry-pick Bot
parent 0fae9692b9
commit 38e986f7e6
5 changed files with 33 additions and 63 deletions

View File

@ -31,12 +31,6 @@ public Q_SLOTS:
void onAppFocusWindowChanged(QWindow *window);
private:
/*
Function to return the default background pixmap.
Needed by QWizard in the Qt widget module.
*/
Q_INVOKABLE QPixmap defaultBackgroundPixmapForQWizard();
Q_INVOKABLE void clearCurrentThreadCocoaEventDispatcherInterruptFlag();
static void registerDraggedTypes(const QStringList &types);

View File

@ -75,35 +75,6 @@ QPlatformNativeInterface::NativeResourceForIntegrationFunction QCocoaNativeInter
return nullptr;
}
QPixmap QCocoaNativeInterface::defaultBackgroundPixmapForQWizard()
{
// Note: starting with macOS 10.14, the KeyboardSetupAssistant app bundle no
// longer contains the "Background.png" image. This function then returns a
// null pixmap.
const int ExpectedImageWidth = 242;
const int ExpectedImageHeight = 414;
QCFType<CFArrayRef> urls = LSCopyApplicationURLsForBundleIdentifier(
CFSTR("com.apple.KeyboardSetupAssistant"), nullptr);
if (urls && CFArrayGetCount(urls) > 0) {
CFURLRef url = (CFURLRef)CFArrayGetValueAtIndex(urls, 0);
QCFType<CFBundleRef> bundle = CFBundleCreate(kCFAllocatorDefault, url);
if (bundle) {
url = CFBundleCopyResourceURL(bundle, CFSTR("Background"), CFSTR("png"), nullptr);
if (url) {
QCFType<CGImageSourceRef> imageSource = CGImageSourceCreateWithURL(url, nullptr);
QCFType<CGImageRef> image = CGImageSourceCreateImageAtIndex(imageSource, 0, nullptr);
if (image) {
int width = CGImageGetWidth(image);
int height = CGImageGetHeight(image);
if (width == ExpectedImageWidth && height == ExpectedImageHeight)
return QPixmap::fromImage(qt_mac_toQImage(image));
}
}
}
}
return QPixmap();
}
void QCocoaNativeInterface::clearCurrentThreadCocoaEventDispatcherInterruptFlag()
{
QCocoaEventDispatcher::clearCurrentThreadCocoaEventDispatcherInterruptFlag();

View File

@ -684,15 +684,25 @@ qt_internal_extend_target(Widgets CONDITION QT_FEATURE_progressdialog
dialogs/qprogressdialog.cpp dialogs/qprogressdialog.h
)
qt_internal_extend_target(Widgets CONDITION QT_FEATURE_wizard
SOURCES
dialogs/qwizard.cpp dialogs/qwizard.h
)
if(QT_FEATURE_wizard)
qt_internal_extend_target(Widgets CONDITION
SOURCES
dialogs/qwizard.cpp dialogs/qwizard.h
)
qt_internal_extend_target(Widgets CONDITION QT_FEATURE_wizard AND WIN32
SOURCES
dialogs/qwizard_win.cpp dialogs/qwizard_win_p.h
)
if(APPLE)
set_source_files_properties(dialogs/qwizard.cpp
PROPERTIES
COMPILE_FLAGS "-x objective-c++"
SKIP_PRECOMPILE_HEADERS ON
)
endif()
qt_internal_extend_target(Widgets CONDITION WIN32
SOURCES
dialogs/qwizard_win.cpp dialogs/qwizard_win_p.h
)
endif()
qt_internal_extend_target(Widgets CONDITION QT_FEATURE_accessibility
SOURCES

View File

@ -29,9 +29,8 @@
#include "qstyleoption.h"
#include "qvarlengtharray.h"
#if defined(Q_OS_MACOS)
#include <QtCore/QMetaMethod>
#include <QtGui/QGuiApplication>
#include <qpa/qplatformnativeinterface.h>
#include <AppKit/AppKit.h>
#include <QtGui/private/qcoregraphics_p.h>
#elif QT_CONFIG(style_windowsvista)
#include "qwizard_win_p.h"
#include "qtimer.h"
@ -1723,23 +1722,19 @@ void QWizardPrivate::setStyle(QStyle *style)
}
#ifdef Q_OS_MACOS
QPixmap QWizardPrivate::findDefaultBackgroundPixmap()
{
QGuiApplication *app = qobject_cast<QGuiApplication *>(QCoreApplication::instance());
if (!app)
return QPixmap();
QPlatformNativeInterface *platformNativeInterface = app->platformNativeInterface();
int at = platformNativeInterface->metaObject()->indexOfMethod("defaultBackgroundPixmapForQWizard()");
if (at == -1)
return QPixmap();
QMetaMethod defaultBackgroundPixmapForQWizard = platformNativeInterface->metaObject()->method(at);
QPixmap result;
if (!defaultBackgroundPixmapForQWizard.invoke(platformNativeInterface, Q_RETURN_ARG(QPixmap, result)))
return QPixmap();
return result;
}
auto *keyboardAssistantURL = [NSWorkspace.sharedWorkspace
URLForApplicationWithBundleIdentifier:@"com.apple.KeyboardSetupAssistant"];
auto *keyboardAssistantBundle = [NSBundle bundleWithURL:keyboardAssistantURL];
auto *assistantBackground = [keyboardAssistantBundle imageForResource:@"Background"];
auto size = QSizeF::fromCGSize(assistantBackground.size);
static const QSizeF expectedSize(242, 414);
if (size == expectedSize)
return qt_mac_toQPixmap(assistantBackground, size);
return QPixmap();
}
#endif
#if QT_CONFIG(style_windowsvista)
@ -2845,7 +2840,7 @@ void QWizard::setPixmap(WizardPixmap which, const QPixmap &pixmap)
Returns the pixmap set for role \a which.
By default, the only pixmap that is set is the BackgroundPixmap on
\macos version 10.13 and earlier.
\macos.
\sa QWizardPage::pixmap(), {Elements of a Wizard Page}
*/

View File

@ -398,7 +398,7 @@ void tst_QWizard::setPixmap()
QVERIFY(wizard.pixmap(QWizard::BannerPixmap).isNull());
QVERIFY(wizard.pixmap(QWizard::LogoPixmap).isNull());
QVERIFY(wizard.pixmap(QWizard::WatermarkPixmap).isNull());
if (QOperatingSystemVersion::current() <= QOperatingSystemVersion::MacOSHighSierra)
if (QOperatingSystemVersion::currentType() == QOperatingSystemVersion::MacOS)
QVERIFY(!wizard.pixmap(QWizard::BackgroundPixmap).isNull());
else
QVERIFY(wizard.pixmap(QWizard::BackgroundPixmap).isNull());
@ -406,7 +406,7 @@ void tst_QWizard::setPixmap()
QVERIFY(page->pixmap(QWizard::BannerPixmap).isNull());
QVERIFY(page->pixmap(QWizard::LogoPixmap).isNull());
QVERIFY(page->pixmap(QWizard::WatermarkPixmap).isNull());
if (QOperatingSystemVersion::current() <= QOperatingSystemVersion::MacOSHighSierra)
if (QOperatingSystemVersion::currentType() == QOperatingSystemVersion::MacOS)
QVERIFY(!wizard.pixmap(QWizard::BackgroundPixmap).isNull());
else
QVERIFY(page->pixmap(QWizard::BackgroundPixmap).isNull());