From 38e986f7e62b4e54da2766fc2afff47fcd4af34a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 15 Feb 2023 12:36:20 +0100 Subject: [PATCH] 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 (cherry picked from commit c26c91b2088a05bbe1ed3b529a4b0fc0ea9d3a92) Reviewed-by: Qt Cherry-pick Bot --- .../platforms/cocoa/qcocoanativeinterface.h | 6 ---- .../platforms/cocoa/qcocoanativeinterface.mm | 29 ----------------- src/widgets/CMakeLists.txt | 26 +++++++++++----- src/widgets/dialogs/qwizard.cpp | 31 ++++++++----------- .../widgets/dialogs/qwizard/tst_qwizard.cpp | 4 +-- 5 files changed, 33 insertions(+), 63 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.h b/src/plugins/platforms/cocoa/qcocoanativeinterface.h index 4a0cf112575..a406cae366c 100644 --- a/src/plugins/platforms/cocoa/qcocoanativeinterface.h +++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.h @@ -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); diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm index e95a3c03312..58bda2706af 100644 --- a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm +++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm @@ -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 urls = LSCopyApplicationURLsForBundleIdentifier( - CFSTR("com.apple.KeyboardSetupAssistant"), nullptr); - if (urls && CFArrayGetCount(urls) > 0) { - CFURLRef url = (CFURLRef)CFArrayGetValueAtIndex(urls, 0); - QCFType bundle = CFBundleCreate(kCFAllocatorDefault, url); - if (bundle) { - url = CFBundleCopyResourceURL(bundle, CFSTR("Background"), CFSTR("png"), nullptr); - if (url) { - QCFType imageSource = CGImageSourceCreateWithURL(url, nullptr); - QCFType 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(); diff --git a/src/widgets/CMakeLists.txt b/src/widgets/CMakeLists.txt index ed9086e19a9..417f6a2d8ee 100644 --- a/src/widgets/CMakeLists.txt +++ b/src/widgets/CMakeLists.txt @@ -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 diff --git a/src/widgets/dialogs/qwizard.cpp b/src/widgets/dialogs/qwizard.cpp index 7cb28314116..da084d412d5 100644 --- a/src/widgets/dialogs/qwizard.cpp +++ b/src/widgets/dialogs/qwizard.cpp @@ -29,9 +29,8 @@ #include "qstyleoption.h" #include "qvarlengtharray.h" #if defined(Q_OS_MACOS) -#include -#include -#include +#include +#include #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(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} */ diff --git a/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp b/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp index a9d5359318f..8739a012773 100644 --- a/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp +++ b/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp @@ -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());