diff options
Diffstat (limited to 'src/plugins/platforms')
22 files changed, 179 insertions, 76 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm index 7644867700a..7ca3e61dfa5 100644 --- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm +++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm @@ -25,6 +25,8 @@ #include <qpa/qwindowsysteminterface.h> #include <qwindowdefs.h> +#include <QtCore/private/qdarwinsecurityscopedfileengine_p.h> + QT_USE_NAMESPACE @implementation QCocoaApplicationDelegate { @@ -194,6 +196,23 @@ QT_USE_NAMESPACE QCocoaMenuBar::insertWindowMenu(); } +/*! + Tells the delegate to open the specified files + + Sent by the system when the user drags a file to the app's icon + in places like Finder or the Dock, or opens a file via the "Open + With" menu in Finder. + + These actions can happen when the application is not running, + in which case the call comes in between willFinishLaunching + and didFinishLaunching. In this case we don't pass on the + incoming file paths as file open events, as the paths are + also part of the command line arguments, and Qt applications + normally expect to handle file opening via those. + + \note The app must register itself as a handler for each file + type via the CFBundleDocumentTypes key in the Info.plist. + */ - (void)application:(NSApplication *)sender openFiles:(NSArray *)filenames { Q_UNUSED(filenames); @@ -209,7 +228,10 @@ QT_USE_NAMESPACE if (qApp->arguments().contains(qtFileName)) continue; } - QWindowSystemInterface::handleFileOpenEvent(qtFileName); + QUrl url = qt_apple_urlFromPossiblySecurityScopedURL([NSURL fileURLWithPath:fileName]); + QWindowSystemInterface::handleFileOpenEvent(url); + // FIXME: We're supposed to call [NSApp replyToOpenOrPrint:] here, but we + // don't know if the open operation succeeded, failed, or was cancelled. } if ([reflectionDelegate respondsToSelector:_cmd]) @@ -262,6 +284,17 @@ QT_USE_NAMESPACE } } +/*! + Returns a Boolean value that indicates if the app responds + to reopen AppleEvents. + + These events are sent whenever the Finder reactivates an already + running application because someone double-clicked it again or used + the dock to activate it. + + We pass the activation on to Qt, and return YES, to let AppKit + follow its normal flow. + */ - (BOOL)applicationShouldHandleReopen:(NSApplication *)theApplication hasVisibleWindows:(BOOL)flag { if ([reflectionDelegate respondsToSelector:_cmd]) @@ -309,6 +342,25 @@ QT_USE_NAMESPACE [self doesNotRecognizeSelector:invocationSelector]; } +/*! + Callback for when the application is asked to pick up a user activity + from another app (also known as Handoff, which is part of the bigger + Continuity story for Apple operating systems). + + This is normally managed by two apps by the same vendor explicitly + initiating a custom NSUserActivity and picking it up in another app + on the same or another device, which we don't have APIs for. + + This is also how the system supports Universal Links, where a web page + can deep-link into an app. In this case the app needs to claim and + validate an associated domain. The resulting link will be delivered + as a special NSUserActivityTypeBrowsingWeb activity type, which we + treat as QDesktopServices::handleUrl(). + + Finally, for NS/UIDocument based apps (which Qt is not), the system + automatically handles document hand-off if the application includes + the NSUbiquitousDocumentUserActivityType key in its Info.plist. + */ - (BOOL)application:(NSApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void(^)(NSArray<id<NSUserActivityRestoring>> *restorableObjects))restorationHandler { @@ -331,6 +383,18 @@ QT_USE_NAMESPACE return NO; } +/*! + Callback for when the app is asked to open custom URL schemes. + + We register a handler for events of type kInternetEventClass with the + NSAppleEventManager during application start. + + The application must include the schemes in the CFBundleURLTypes + key of the Info.plist. + + \note This callback is not used for http/https URLs, see + continueUserActivity above for how we handle that. + */ - (void)getUrl:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent { Q_UNUSED(replyEvent); diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm index 4c4e5fac962..a79682e4e14 100644 --- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm +++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm @@ -19,6 +19,7 @@ #include <QtCore/qregularexpression.h> #include <QtCore/qpointer.h> #include <QtCore/private/qcore_mac_p.h> +#include <QtCore/private/qdarwinsecurityscopedfileengine_p.h> #include <QtGui/qguiapplication.h> #include <QtGui/private/qguiapplication_p.h> @@ -395,14 +396,15 @@ typedef QSharedPointer<QFileDialogOptions> SharedPointerFileDialogOptions; { if (auto *openPanel = openpanel_cast(m_panel)) { QList<QUrl> result; - for (NSURL *url in openPanel.URLs) { - QString path = QString::fromNSString(url.path).normalized(QString::NormalizationForm_C); - result << QUrl::fromLocalFile(path); - } + for (NSURL *url in openPanel.URLs) + result << qt_apple_urlFromPossiblySecurityScopedURL(url); return result; } else { - QString filename = QString::fromNSString(m_panel.URL.path).normalized(QString::NormalizationForm_C); - QFileInfo fileInfo(filename); + QUrl result = qt_apple_urlFromPossiblySecurityScopedURL(m_panel.URL); + if (qt_apple_isSandboxed()) + return { result }; // Can't tweak suffix + + QFileInfo fileInfo(result.toLocalFile()); if (fileInfo.suffix().isEmpty() && ![self fileInfoMatchesCurrentNameFilter:fileInfo]) { // We end up in this situation if we accept a file name without extension @@ -733,6 +735,26 @@ bool QCocoaFileDialogHelper::show(Qt::WindowFlags windowFlags, Qt::WindowModalit return false; } + if (qt_apple_isSandboxed()) { + static bool canRead = qt_mac_processHasEntitlement( + u"com.apple.security.files.user-selected.read-only"_s); + static bool canReadWrite = qt_mac_processHasEntitlement( + u"com.apple.security.files.user-selected.read-write"_s); + + if (options()->acceptMode() == QFileDialogOptions::AcceptSave + && !canReadWrite) { + qWarning() << "Sandboxed application is missing user-selected files" + << "read-write entitlement. Falling back to non-native dialog"; + return false; + } + + if (!canReadWrite && !canRead) { + qWarning() << "Sandboxed application is missing user-selected files" + << "entitlement. Falling back to non-native dialog"; + return false; + } + } + createNSOpenSavePanelDelegate(); return [m_delegate showPanel:windowModality withParent:parent]; diff --git a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.h b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.h index 9a491d4d058..35fb7f24dd5 100644 --- a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.h +++ b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.h @@ -29,7 +29,7 @@ Q_FORWARD_DECLARE_OBJC_CLASS(NSStatusItem); QT_BEGIN_NAMESPACE -class Q_GUI_EXPORT QCocoaSystemTrayIcon : public QPlatformSystemTrayIcon +class QCocoaSystemTrayIcon : public QPlatformSystemTrayIcon { public: QCocoaSystemTrayIcon() {} diff --git a/src/plugins/platforms/ios/qiosapplicationdelegate.mm b/src/plugins/platforms/ios/qiosapplicationdelegate.mm index 380c5a588e6..7cbb4fc40f5 100644 --- a/src/plugins/platforms/ios/qiosapplicationdelegate.mm +++ b/src/plugins/platforms/ios/qiosapplicationdelegate.mm @@ -16,6 +16,8 @@ #include <QtCore/QtCore> +#include <QtCore/private/qdarwinsecurityscopedfileengine_p.h> + @interface QIOSWindowSceneDelegate : NSObject<UIWindowSceneDelegate> @property (nullable, nonatomic, strong) UIWindow *window; @end @@ -112,7 +114,7 @@ QIOSServices *iosServices = static_cast<QIOSServices *>(iosIntegration->services()); for (UIOpenURLContext *urlContext in URLContexts) { - QUrl url = QUrl::fromNSURL(urlContext.URL); + QUrl url = qt_apple_urlFromPossiblySecurityScopedURL(urlContext.URL); if (url.isLocalFile()) QWindowSystemInterface::handleFileOpenEvent(url); else diff --git a/src/plugins/platforms/ios/qiosdocumentpickercontroller.mm b/src/plugins/platforms/ios/qiosdocumentpickercontroller.mm index c173aa426fc..57a5e100c9e 100644 --- a/src/plugins/platforms/ios/qiosdocumentpickercontroller.mm +++ b/src/plugins/platforms/ios/qiosdocumentpickercontroller.mm @@ -8,6 +8,7 @@ #include "qiosdocumentpickercontroller.h" #include <QtCore/qpointer.h> +#include <QtCore/private/qdarwinsecurityscopedfileengine_p.h> @implementation QIOSDocumentPickerController { QPointer<QIOSFileDialog> m_fileDialog; @@ -17,9 +18,11 @@ { NSMutableArray <UTType *> *docTypes = [[[NSMutableArray alloc] init] autorelease]; - QStringList nameFilters = fileDialog->options()->nameFilters(); - if (!nameFilters.isEmpty() && (fileDialog->options()->fileMode() != QFileDialogOptions::Directory - || fileDialog->options()->fileMode() != QFileDialogOptions::DirectoryOnly)) + const auto options = fileDialog->options(); + + const QStringList nameFilters = options->nameFilters(); + if (!nameFilters.isEmpty() && (options->fileMode() != QFileDialogOptions::Directory + || options->fileMode() != QFileDialogOptions::DirectoryOnly)) { QStringList results; for (const QString &filter : nameFilters) @@ -28,21 +31,8 @@ docTypes = [self computeAllowedFileTypes:results]; } - // FIXME: Handle security scoped URLs instead of copying resource - bool asCopy = [&]{ - switch (fileDialog->options()->fileMode()) { - case QFileDialogOptions::AnyFile: - case QFileDialogOptions::ExistingFile: - case QFileDialogOptions::ExistingFiles: - return true; - default: - // Folders can't be imported - return false; - } - }(); - if (!docTypes.count) { - switch (fileDialog->options()->fileMode()) { + switch (options->fileMode()) { case QFileDialogOptions::AnyFile: case QFileDialogOptions::ExistingFile: case QFileDialogOptions::ExistingFiles: @@ -58,17 +48,39 @@ } } - if (self = [super initForOpeningContentTypes:docTypes asCopy:asCopy]) { - m_fileDialog = fileDialog; - self.modalPresentationStyle = UIModalPresentationFormSheet; - self.delegate = self; - self.presentationController.delegate = self; + if (options->acceptMode() == QFileDialogOptions::AcceptSave) { + auto selectedUrls = options->initiallySelectedFiles(); + auto suggestedFileName = !selectedUrls.isEmpty() ? selectedUrls.first().fileName() : "Untitled"; - if (m_fileDialog->options()->fileMode() == QFileDialogOptions::ExistingFiles) + // Create an empty dummy file, so that the export dialog will allow us + // to choose the export destination, which we are then given access to + // write to. + NSURL *dummyExportFile = [NSFileManager.defaultManager.temporaryDirectory + URLByAppendingPathComponent:suggestedFileName.toNSString()]; + [NSFileManager.defaultManager createFileAtPath:dummyExportFile.path contents:nil attributes:nil]; + + if (!(self = [super initForExportingURLs:@[dummyExportFile]])) + return nil; + + // Note, we don't set the directoryURL, as if the directory can't be + // accessed, or written to, the file dialog is shown but is empty. + // FIXME: See comment below for open dialogs as well + } else { + if (!(self = [super initForOpeningContentTypes:docTypes asCopy:NO])) + return nil; + + if (options->fileMode() == QFileDialogOptions::ExistingFiles) self.allowsMultipleSelection = YES; - self.directoryURL = m_fileDialog->options()->initialDirectory().toNSURL(); + // FIXME: This doesn't seem to have any effect + self.directoryURL = options->initialDirectory().toNSURL(); } + + m_fileDialog = fileDialog; + self.modalPresentationStyle = UIModalPresentationFormSheet; + self.delegate = self; + self.presentationController.delegate = self; + return self; } @@ -81,7 +93,7 @@ QList<QUrl> files; for (NSURL* url in urls) - files.append(QUrl::fromNSURL(url)); + files.append(qt_apple_urlFromPossiblySecurityScopedURL(url)); m_fileDialog->selectedFilesChanged(files); emit m_fileDialog->accept(); diff --git a/src/plugins/platforms/ios/qiosfiledialog.mm b/src/plugins/platforms/ios/qiosfiledialog.mm index b7d3e488bbb..6e7c10117ed 100644 --- a/src/plugins/platforms/ios/qiosfiledialog.mm +++ b/src/plugins/platforms/ios/qiosfiledialog.mm @@ -49,14 +49,10 @@ bool QIOSFileDialog::show(Qt::WindowFlags windowFlags, Qt::WindowModality window // when converted to QUrl, it becames a scheme. const QString scheme = initialDir.scheme(); - if (acceptOpen) { - if (directory.startsWith("assets-library:"_L1) || scheme == "assets-library"_L1) - return showImagePickerDialog(parent); - else - return showNativeDocumentPickerDialog(parent); - } + if (acceptOpen && (directory.startsWith("assets-library:"_L1) || scheme == "assets-library"_L1)) + return showImagePickerDialog(parent); - return false; + return showNativeDocumentPickerDialog(parent); } void QIOSFileDialog::showImagePickerDialog_helper(QWindow *parent) diff --git a/src/plugins/platforms/wayland/plugins/hardwareintegration/dmabuf-server/dmabufserverbufferintegration.h b/src/plugins/platforms/wayland/plugins/hardwareintegration/dmabuf-server/dmabufserverbufferintegration.h index 13dbdfbfbab..ba3d293e054 100644 --- a/src/plugins/platforms/wayland/plugins/hardwareintegration/dmabuf-server/dmabufserverbufferintegration.h +++ b/src/plugins/platforms/wayland/plugins/hardwareintegration/dmabuf-server/dmabufserverbufferintegration.h @@ -9,7 +9,6 @@ #include "qwayland-qt-dmabuf-server-buffer.h" #include <QtWaylandClient/private/qwaylandserverbufferintegration_p.h> -#include "dmabufserverbufferintegration.h" #include <QtWaylandClient/private/qwaylanddisplay_p.h> #include <QtCore/QTextStream> diff --git a/src/plugins/platforms/wayland/plugins/hardwareintegration/drm-egl-server/drmeglserverbufferintegration.h b/src/plugins/platforms/wayland/plugins/hardwareintegration/drm-egl-server/drmeglserverbufferintegration.h index a06bc96b87d..01ac4dbe718 100644 --- a/src/plugins/platforms/wayland/plugins/hardwareintegration/drm-egl-server/drmeglserverbufferintegration.h +++ b/src/plugins/platforms/wayland/plugins/hardwareintegration/drm-egl-server/drmeglserverbufferintegration.h @@ -9,7 +9,6 @@ #include "qwayland-drm-egl-server-buffer.h" #include <QtWaylandClient/private/qwaylandserverbufferintegration_p.h> -#include "drmeglserverbufferintegration.h" #include <QtWaylandClient/private/qwaylanddisplay_p.h> #include <QtCore/QTextStream> diff --git a/src/plugins/platforms/wayland/plugins/hardwareintegration/shm-emulation-server/shmserverbufferintegration.h b/src/plugins/platforms/wayland/plugins/hardwareintegration/shm-emulation-server/shmserverbufferintegration.h index 344046ae182..4f9e0aeced5 100644 --- a/src/plugins/platforms/wayland/plugins/hardwareintegration/shm-emulation-server/shmserverbufferintegration.h +++ b/src/plugins/platforms/wayland/plugins/hardwareintegration/shm-emulation-server/shmserverbufferintegration.h @@ -8,7 +8,6 @@ #include "qwayland-shm-emulation-server-buffer.h" #include <QtWaylandClient/private/qwaylandserverbufferintegration_p.h> -#include "shmserverbufferintegration.h" #include <QtWaylandClient/private/qwaylanddisplay_p.h> #include <QtCore/QTextStream> diff --git a/src/plugins/platforms/wayland/plugins/hardwareintegration/vulkan-server/vulkanserverbufferintegration.h b/src/plugins/platforms/wayland/plugins/hardwareintegration/vulkan-server/vulkanserverbufferintegration.h index 2f0867a8197..a1c413be5d9 100644 --- a/src/plugins/platforms/wayland/plugins/hardwareintegration/vulkan-server/vulkanserverbufferintegration.h +++ b/src/plugins/platforms/wayland/plugins/hardwareintegration/vulkan-server/vulkanserverbufferintegration.h @@ -8,7 +8,6 @@ #include "qwayland-qt-vulkan-server-buffer-unstable-v1.h" #include <QtWaylandClient/private/qwaylandserverbufferintegration_p.h> -#include "vulkanserverbufferintegration.h" #include <QtWaylandClient/private/qwaylanddisplay_p.h> #include <QtCore/QTextStream> diff --git a/src/plugins/platforms/wayland/plugins/shellintegration/wl-shell/qwaylandwlshellsurface_p.h b/src/plugins/platforms/wayland/plugins/shellintegration/wl-shell/qwaylandwlshellsurface_p.h index 780f5f3268e..6d86600bad2 100644 --- a/src/plugins/platforms/wayland/plugins/shellintegration/wl-shell/qwaylandwlshellsurface_p.h +++ b/src/plugins/platforms/wayland/plugins/shellintegration/wl-shell/qwaylandwlshellsurface_p.h @@ -82,8 +82,8 @@ private: friend class QWaylandWindow; }; -QT_END_NAMESPACE +} // namespace QtWaylandClient -} +QT_END_NAMESPACE #endif // QWAYLANDSHELLSURFACE_H diff --git a/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgactivationv1_p.h b/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgactivationv1_p.h index bddb5c614e0..e2c54ef0078 100644 --- a/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgactivationv1_p.h +++ b/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgactivationv1_p.h @@ -52,8 +52,7 @@ public: const QString &app_id); }; -QT_END_NAMESPACE - -} +} // namespace QtWaylandClient +QT_END_NAMESPACE #endif // QWAYLANDXDGACTIVATIONV1_P_H diff --git a/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgdecorationv1_p.h b/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgdecorationv1_p.h index 8a0cc9e79a7..680fcf69b9f 100644 --- a/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgdecorationv1_p.h +++ b/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgdecorationv1_p.h @@ -56,8 +56,7 @@ private: bool m_configured = false; }; -QT_END_NAMESPACE - -} +} // namespace QtWaylandClient +QT_END_NAMESPACE #endif // QWAYLANDXDGDECORATIONV1_P_H diff --git a/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h b/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h index a12311eff74..43c17672c23 100644 --- a/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h +++ b/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h @@ -201,8 +201,7 @@ private: friend class QWaylandXdgSurface; }; -QT_END_NAMESPACE - -} +} // namespace QtWaylandClient +QT_END_NAMESPACE #endif // QWAYLANDXDGSHELL_H diff --git a/src/plugins/platforms/wayland/qwaylandinputcontext.cpp b/src/plugins/platforms/wayland/qwaylandinputcontext.cpp index 5ab285ad97d..0ccc4dba57a 100644 --- a/src/plugins/platforms/wayland/qwaylandinputcontext.cpp +++ b/src/plugins/platforms/wayland/qwaylandinputcontext.cpp @@ -192,12 +192,10 @@ void QWaylandInputContext::setFocusObject(QObject *object) if (window && window->handle()) { if (mCurrentWindow.data() != window) { if (!inputMethodAccepted()) { - if (mCurrentWindow) { - auto *surface = static_cast<QWaylandWindow *>(mCurrentWindow->handle())->wlSurface(); - if (surface) - inputInterface->disableSurface(surface); - mCurrentWindow.clear(); - } + auto *surface = static_cast<QWaylandWindow *>(window->handle())->wlSurface(); + if (surface) + inputInterface->disableSurface(surface); + mCurrentWindow.clear(); } else { auto *surface = static_cast<QWaylandWindow *>(window->handle())->wlSurface(); if (surface) { diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp index 2bd2f0c9e3d..0236669d6fb 100644 --- a/src/plugins/platforms/windows/qwindowsscreen.cpp +++ b/src/plugins/platforms/windows/qwindowsscreen.cpp @@ -704,7 +704,7 @@ void QWindowsScreenManager::initialize() qCDebug(lcQpaScreen) << "Initializing screen manager"; auto className = QWindowsWindowClassRegistry::instance()->registerWindowClass( - QLatin1String("ScreenChangeObserverWindow"), + "ScreenChangeObserverWindow"_L1, qDisplayChangeObserverWndProc); // HWND_MESSAGE windows do not get WM_DISPLAYCHANGE, so we need to create diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp index d132bbb6130..b9f60f7713c 100644 --- a/src/plugins/platforms/windows/qwindowstheme.cpp +++ b/src/plugins/platforms/windows/qwindowstheme.cpp @@ -549,7 +549,7 @@ QWindowsTheme::QWindowsTheme() refreshIconPixmapSizes(); auto className = QWindowsWindowClassRegistry::instance()->registerWindowClass( - QLatin1String("ThemeChangeObserverWindow"), + "ThemeChangeObserverWindow"_L1, qThemeChangeObserverWndProc); // HWND_MESSAGE windows do not get the required theme events, // so we use a real top-level window that we never show. diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index ed391009423..b77e985c965 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -61,6 +61,8 @@ QT_BEGIN_NAMESPACE +using namespace Qt::StringLiterals; + using QWindowCreationContextPtr = QSharedPointer<QWindowCreationContext>; enum { @@ -889,7 +891,7 @@ QWindowsWindowData const QString windowClassName = QWindowsWindowClassRegistry::instance()->registerWindowClass(w); QWindowsWindowClassDescription windowTitlebarDescription; - windowTitlebarDescription.name = QStringLiteral("_q_titlebar"); + windowTitlebarDescription.name = "_q_titlebar"_L1; windowTitlebarDescription.style = CS_VREDRAW | CS_HREDRAW; windowTitlebarDescription.shouldAddPrefix = false; const QString windowTitlebarName = QWindowsWindowClassRegistry::instance()->registerWindowClass(windowTitlebarDescription); diff --git a/src/plugins/platforms/windows/qwindowswindowclassdescription.cpp b/src/plugins/platforms/windows/qwindowswindowclassdescription.cpp index 63e16260b62..e2e46a7b215 100644 --- a/src/plugins/platforms/windows/qwindowswindowclassdescription.cpp +++ b/src/plugins/platforms/windows/qwindowswindowclassdescription.cpp @@ -75,4 +75,14 @@ QWindowsWindowClassDescription QWindowsWindowClassDescription::fromWindow(const return description; } +QDebug operator<<(QDebug dbg, const QWindowsWindowClassDescription &description) +{ + dbg << description.name + << " style=0x" << Qt::hex << description.style << Qt::dec + << " brush=" << description.brush + << " hasIcon=" << description.hasIcon; + + return dbg; +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowswindowclassdescription.h b/src/plugins/platforms/windows/qwindowswindowclassdescription.h index 9423abf9d2d..3acca65b8a2 100644 --- a/src/plugins/platforms/windows/qwindowswindowclassdescription.h +++ b/src/plugins/platforms/windows/qwindowswindowclassdescription.h @@ -23,6 +23,9 @@ struct QWindowsWindowClassDescription HBRUSH brush{ nullptr }; bool hasIcon{ false }; bool shouldAddPrefix{ true }; + +private: + friend QDebug operator<<(QDebug dbg, const QWindowsWindowClassDescription &description); }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowswindowclassregistry.cpp b/src/plugins/platforms/windows/qwindowswindowclassregistry.cpp index c330720a09c..c918407a27a 100644 --- a/src/plugins/platforms/windows/qwindowswindowclassregistry.cpp +++ b/src/plugins/platforms/windows/qwindowswindowclassregistry.cpp @@ -18,8 +18,8 @@ Q_LOGGING_CATEGORY(lcQpaWindowClass, "qt.qpa.windowclass") QWindowsWindowClassRegistry *QWindowsWindowClassRegistry::m_instance = nullptr; -QWindowsWindowClassRegistry::QWindowsWindowClassRegistry(WNDPROC proc) - : m_proc(proc) +QWindowsWindowClassRegistry::QWindowsWindowClassRegistry(WNDPROC defaultProcedure) + : m_defaultProcedure(defaultProcedure) { m_instance = this; } @@ -110,19 +110,19 @@ QString QWindowsWindowClassRegistry::registerWindowClass(const QWindowsWindowCla wc.lpszClassName = reinterpret_cast<LPCWSTR>(className.utf16()); ATOM atom = RegisterClassEx(&wc); if (!atom) - qErrnoWarning("QApplication::regClass: Registering window class '%s' failed.", - qPrintable(className)); + qCWarning(lcQpaWindowClass) << "Failed to register window class" << className + << "(" << qt_error_string(-1) << ")"; m_registeredWindowClassNames.insert(className); - qCDebug(lcQpaWindowClass).nospace() << __FUNCTION__ << ' ' << className - << " style=0x" << Qt::hex << description.style << Qt::dec - << " brush=" << description.brush << " icon=" << description.hasIcon << " atom=" << atom; + + qCDebug(lcQpaWindowClass).nospace() << __FUNCTION__ << ' ' << className << ' ' << description << " atom=" << atom; + return className; } QString QWindowsWindowClassRegistry::registerWindowClass(const QWindow *window) { - return registerWindowClass(QWindowsWindowClassDescription::fromWindow(window, m_proc)); + return registerWindowClass(QWindowsWindowClassDescription::fromWindow(window, m_defaultProcedure)); } QString QWindowsWindowClassRegistry::registerWindowClass(QString name, WNDPROC procedure) @@ -136,7 +136,8 @@ void QWindowsWindowClassRegistry::unregisterWindowClasses() for (const QString &name : std::as_const(m_registeredWindowClassNames)) { if (!UnregisterClass(reinterpret_cast<LPCWSTR>(name.utf16()), appInstance) && QWindowsContext::verbose) - qErrnoWarning("UnregisterClass failed for '%s'", qPrintable(name)); + qCWarning(lcQpaWindowClass) << "Failed to unregister window class" << name + << "(" << qt_error_string(-1) << ")"; } m_registeredWindowClassNames.clear(); } diff --git a/src/plugins/platforms/windows/qwindowswindowclassregistry.h b/src/plugins/platforms/windows/qwindowswindowclassregistry.h index c19b4f616fb..44f274de2b2 100644 --- a/src/plugins/platforms/windows/qwindowswindowclassregistry.h +++ b/src/plugins/platforms/windows/qwindowswindowclassregistry.h @@ -22,7 +22,7 @@ class QWindowsWindowClassRegistry { Q_DISABLE_COPY_MOVE(QWindowsWindowClassRegistry) public: - QWindowsWindowClassRegistry(WNDPROC proc); + QWindowsWindowClassRegistry(WNDPROC defaultProcedure); ~QWindowsWindowClassRegistry(); static QWindowsWindowClassRegistry *instance(); @@ -38,7 +38,7 @@ private: static QWindowsWindowClassRegistry *m_instance; - WNDPROC m_proc; + WNDPROC m_defaultProcedure; QSet<QString> m_registeredWindowClassNames; }; |
