diff options
Diffstat (limited to 'src/plugins/platforms')
22 files changed, 222 insertions, 43 deletions
diff --git a/src/plugins/platforms/android/androidjniaccessibility.cpp b/src/plugins/platforms/android/androidjniaccessibility.cpp index e4d670239f..a3bc58bb89 100644 --- a/src/plugins/platforms/android/androidjniaccessibility.cpp +++ b/src/plugins/platforms/android/androidjniaccessibility.cpp @@ -105,15 +105,15 @@ namespace QtAndroidAccessibility { QAccessibleInterface *iface = interfaceFromId(objectId); if (iface && iface->isValid()) { - jintArray jArray = env->NewIntArray(jsize(iface->childCount())); - for (int i = 0; i < iface->childCount(); ++i) { + const int childCount = iface->childCount(); + QVarLengthArray<jint, 8> ifaceIdArray(childCount); + for (int i = 0; i < childCount; ++i) { QAccessibleInterface *child = iface->child(i); - if (child && child->isValid()) { - QAccessible::Id ifaceId = QAccessible::uniqueId(child); - jint jid = ifaceId; - env->SetIntArrayRegion(jArray, i, 1, &jid); - } + if (child && child->isValid()) + ifaceIdArray.append(QAccessible::uniqueId(child)); } + jintArray jArray = env->NewIntArray(jsize(ifaceIdArray.count())); + env->SetIntArrayRegion(jArray, 0, ifaceIdArray.count(), ifaceIdArray.data()); return jArray; } diff --git a/src/plugins/platforms/cocoa/messages.cpp b/src/plugins/platforms/cocoa/messages.cpp index 85b814ce1c..8eea1e654e 100644 --- a/src/plugins/platforms/cocoa/messages.cpp +++ b/src/plugins/platforms/cocoa/messages.cpp @@ -75,7 +75,7 @@ QString qt_mac_applicationmenu_string(int type) QPlatformMenuItem::MenuRole detectMenuRole(const QString &caption) { QString captionNoAmpersand(caption); - captionNoAmpersand.remove(QChar('&')); + captionNoAmpersand.remove(QLatin1Char('&')); const QString aboutString = QCoreApplication::translate("QCocoaMenuItem", "About"); if (captionNoAmpersand.startsWith(aboutString, Qt::CaseInsensitive) || caption.endsWith(aboutString, Qt::CaseInsensitive)) return QPlatformMenuItem::AboutRole; diff --git a/src/plugins/platforms/cocoa/messages.h b/src/plugins/platforms/cocoa/messages.h index a9c9cc42e5..e41898fe59 100644 --- a/src/plugins/platforms/cocoa/messages.h +++ b/src/plugins/platforms/cocoa/messages.h @@ -45,6 +45,17 @@ QT_BEGIN_NAMESPACE +enum { + ServicesAppMenuItem = 0, + HideAppMenuItem, + HideOthersAppMenuItem, + ShowAllAppMenuItem, + PreferencesAppMenuItem, + QuitAppMenuItem, + AboutAppMenuItem +}; + + QString msgAboutQt(); QString qt_mac_applicationmenu_string(int type); diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.h b/src/plugins/platforms/cocoa/qcocoaintegration.h index 9fa7487623..301771fd53 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.h +++ b/src/plugins/platforms/cocoa/qcocoaintegration.h @@ -60,8 +60,9 @@ QT_BEGIN_NAMESPACE class QCocoaScreen; -class QCocoaIntegration : public QPlatformIntegration +class QCocoaIntegration : public QObject, public QPlatformIntegration { + Q_OBJECT public: enum Option { UseFreeTypeFontEngine = 0x1 @@ -120,6 +121,9 @@ public: void beep() const override; +private Q_SLOTS: + void focusWindowChanged(QWindow *); + private: static QCocoaIntegration *mInstance; Options mOptions; diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index dd17848109..55b3805df3 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -179,6 +179,9 @@ QCocoaIntegration::QCocoaIntegration(const QStringList ¶mList) QMacInternalPasteboardMime::initializeMimeTypes(); QCocoaMimeTypes::initializeMimeTypes(); QWindowSystemInterfacePrivate::TabletEvent::setPlatformSynthesizesMouse(false); + + connect(qGuiApp, &QGuiApplication::focusWindowChanged, + this, &QCocoaIntegration::focusWindowChanged); } QCocoaIntegration::~QCocoaIntegration() @@ -222,6 +225,8 @@ QCocoaIntegration::Options QCocoaIntegration::options() const return mOptions; } +Q_LOGGING_CATEGORY(lcCocoaScreen, "qt.qpa.cocoa.screens"); + /*! \brief Synchronizes the screen list, adds new screens, removes deleted ones */ @@ -261,9 +266,11 @@ void QCocoaIntegration::updateScreens() if (screen) { remainingScreens.remove(screen); screen->updateGeometry(); + qCDebug(lcCocoaScreen) << "Updated properties of" << screen; } else { screen = new QCocoaScreen(i); mScreens.append(screen); + qCDebug(lcCocoaScreen) << "Adding" << screen; screenAdded(screen); } siblings << screen; @@ -280,6 +287,7 @@ void QCocoaIntegration::updateScreens() mScreens.removeOne(screen); // Prevent stale references to NSScreen during destroy screen->m_screenIndex = -1; + qCDebug(lcCocoaScreen) << "Removing" << screen; destroyScreen(screen); } } @@ -505,4 +513,33 @@ void QCocoaIntegration::beep() const NSBeep(); } +void QCocoaIntegration::focusWindowChanged(QWindow *focusWindow) +{ + // Don't revert icon just because we lost focus + if (!focusWindow) + return; + + static bool hasDefaultApplicationIcon = [](){ + NSImage *genericApplicationIcon = [[NSWorkspace sharedWorkspace] + iconForFileType:NSFileTypeForHFSTypeCode(kGenericApplicationIcon)]; + NSImage *applicationIcon = [NSImage imageNamed:NSImageNameApplicationIcon]; + + NSRect rect = NSMakeRect(0, 0, 32, 32); + return [applicationIcon CGImageForProposedRect:&rect context:nil hints:nil] + == [genericApplicationIcon CGImageForProposedRect:&rect context:nil hints:nil]; + }(); + + // Don't let the window icon override an explicit application icon set in the Info.plist + if (!hasDefaultApplicationIcon) + return; + + // Or an explicit application icon set on QGuiApplication + if (!qGuiApp->windowIcon().isNull()) + return; + + setApplicationIcon(focusWindow->icon()); +} + +#include "moc_qcocoaintegration.cpp" + QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoamenu.h b/src/plugins/platforms/cocoa/qcocoamenu.h index 4392de2f9b..f5fa93cbb5 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.h +++ b/src/plugins/platforms/cocoa/qcocoamenu.h @@ -93,6 +93,8 @@ public: void timerEvent(QTimerEvent *e) override; + void syncMenuItem_helper(QPlatformMenuItem *menuItem, bool menubarUpdate); + private: QCocoaMenuItem *itemOrNull(int index) const; void insertNative(QCocoaMenuItem *item, QCocoaMenuItem *beforeItem); diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm index eeb4c01791..a54284dbae 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.mm +++ b/src/plugins/platforms/cocoa/qcocoamenu.mm @@ -434,6 +434,11 @@ void QCocoaMenu::timerEvent(QTimerEvent *e) void QCocoaMenu::syncMenuItem(QPlatformMenuItem *menuItem) { + syncMenuItem_helper(menuItem, false /*menubarUpdate*/); +} + +void QCocoaMenu::syncMenuItem_helper(QPlatformMenuItem *menuItem, bool menubarUpdate) +{ QMacAutoReleasePool pool; QCocoaMenuItem *cocoaItem = static_cast<QCocoaMenuItem *>(menuItem); if (!m_menuItems.contains(cocoaItem)) { @@ -443,8 +448,9 @@ void QCocoaMenu::syncMenuItem(QPlatformMenuItem *menuItem) const bool wasMerged = cocoaItem->isMerged(); NSMenuItem *oldItem = cocoaItem->nsItem(); + NSMenuItem *syncedItem = cocoaItem->sync(); - if (cocoaItem->sync() != oldItem) { + if (syncedItem != oldItem) { // native item was changed for some reason if (oldItem) { if (wasMerged) { @@ -462,6 +468,14 @@ void QCocoaMenu::syncMenuItem(QPlatformMenuItem *menuItem) // when an item's enabled state changes after menuWillOpen: scheduleUpdate(); } + + // This may be a good moment to attach this item's eventual submenu to the + // synced item, but only on the condition we're all currently hooked to the + // menunbar. A good indicator of this being the right moment is knowing that + // we got called from QCocoaMenuBar::updateMenuBarImmediately(). + if (menubarUpdate) + if (QCocoaMenu *submenu = cocoaItem->menu()) + submenu->setAttachedItem(syncedItem); } void QCocoaMenu::syncSeparatorsCollapsible(bool enable) diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.h b/src/plugins/platforms/cocoa/qcocoamenubar.h index 0a46e80695..32a8fd89b4 100644 --- a/src/plugins/platforms/cocoa/qcocoamenubar.h +++ b/src/plugins/platforms/cocoa/qcocoamenubar.h @@ -72,6 +72,8 @@ public: QList<QCocoaMenuItem*> merged() const; NSMenuItem *itemForRole(QPlatformMenuItem::MenuRole r); + void syncMenu_helper(QPlatformMenu *menu, bool menubarUpdate); + private: static QCocoaWindow *findWindowForMenubar(); static QCocoaMenuBar *findGlobalMenubar(); diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.mm b/src/plugins/platforms/cocoa/qcocoamenubar.mm index 36655dffab..fd28a4d7da 100644 --- a/src/plugins/platforms/cocoa/qcocoamenubar.mm +++ b/src/plugins/platforms/cocoa/qcocoamenubar.mm @@ -155,7 +155,7 @@ void QCocoaMenuBar::insertMenu(QPlatformMenu *platformMenu, QPlatformMenu *befor } } - syncMenu(menu); + syncMenu_helper(menu, false /*internaCall*/); if (needsImmediateUpdate()) updateMenuBarImmediately(); @@ -183,11 +183,16 @@ void QCocoaMenuBar::removeMenu(QPlatformMenu *platformMenu) void QCocoaMenuBar::syncMenu(QPlatformMenu *menu) { + syncMenu_helper(menu, false /*internaCall*/); +} + +void QCocoaMenuBar::syncMenu_helper(QPlatformMenu *menu, bool menubarUpdate) +{ QMacAutoReleasePool pool; QCocoaMenu *cocoaMenu = static_cast<QCocoaMenu *>(menu); Q_FOREACH (QCocoaMenuItem *item, cocoaMenu->items()) - cocoaMenu->syncMenuItem(item); + cocoaMenu->syncMenuItem_helper(item, menubarUpdate); BOOL shouldHide = YES; if (cocoaMenu->isVisible()) { @@ -357,7 +362,7 @@ void QCocoaMenuBar::updateMenuBarImmediately() menu->setAttachedItem(item); menu->setMenuParent(mb); // force a sync? - mb->syncMenu(menu); + mb->syncMenu_helper(menu, true /*menubarUpdate*/); menu->propagateEnabledState(!disableForModal); } diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm index d135b244e0..eaf310ec51 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm +++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm @@ -149,10 +149,6 @@ void QCocoaMenuItem::setMenu(QPlatformMenu *menu) QMacAutoReleasePool pool; m_menu = static_cast<QCocoaMenu *>(menu); if (m_menu) { - if (m_native) { - // Skip automatic menu item validation - m_native.action = nil; - } m_menu->setMenuParent(this); m_menu->propagateEnabledState(isEnabled()); } else { @@ -369,24 +365,20 @@ NSMenuItem *QCocoaMenuItem::sync() return m_native; } -QT_BEGIN_NAMESPACE -extern QString qt_mac_applicationmenu_string(int type); -QT_END_NAMESPACE - QString QCocoaMenuItem::mergeText() { QCocoaMenuLoader *loader = [QCocoaMenuLoader sharedMenuLoader]; if (m_native == [loader aboutMenuItem]) { - return qt_mac_applicationmenu_string(6).arg(qt_mac_applicationName()); + return qt_mac_applicationmenu_string(AboutAppMenuItem).arg(qt_mac_applicationName()); } else if (m_native== [loader aboutQtMenuItem]) { if (m_text == QString("About Qt")) return msgAboutQt(); else return m_text; } else if (m_native == [loader preferencesMenuItem]) { - return qt_mac_applicationmenu_string(4); + return qt_mac_applicationmenu_string(PreferencesAppMenuItem); } else if (m_native == [loader quitMenuItem]) { - return qt_mac_applicationmenu_string(5).arg(qt_mac_applicationName()); + return qt_mac_applicationmenu_string(QuitAppMenuItem).arg(qt_mac_applicationName()); } else if (m_text.contains('\t')) { return m_text.left(m_text.indexOf('\t')); } diff --git a/src/plugins/platforms/cocoa/qcocoamenuloader.mm b/src/plugins/platforms/cocoa/qcocoamenuloader.mm index 01a3c04afb..0d9bb5009d 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuloader.mm +++ b/src/plugins/platforms/cocoa/qcocoamenuloader.mm @@ -47,14 +47,8 @@ #include <QtCore/private/qcore_mac_p.h> #include <QtCore/private/qthread_p.h> #include <QtCore/qcoreapplication.h> -#include <QtCore/qdir.h> -#include <QtCore/qstring.h> -#include <QtCore/qdebug.h> #include <QtGui/private/qguiapplication_p.h> -QT_FORWARD_DECLARE_CLASS(QCFString) -QT_FORWARD_DECLARE_CLASS(QString) - @implementation QCocoaMenuLoader + (instancetype)sharedMenuLoader @@ -314,13 +308,13 @@ QT_FORWARD_DECLARE_CLASS(QString) { #ifndef QT_NO_TRANSLATION - [servicesItem setTitle:qt_mac_applicationmenu_string(0).toNSString()]; - [hideItem setTitle:qt_mac_applicationmenu_string(1).arg(qt_mac_applicationName()).toNSString()]; - [hideAllOthersItem setTitle:qt_mac_applicationmenu_string(2).toNSString()]; - [showAllItem setTitle:qt_mac_applicationmenu_string(3).toNSString()]; - [preferencesItem setTitle:qt_mac_applicationmenu_string(4).toNSString()]; - [quitItem setTitle:qt_mac_applicationmenu_string(5).arg(qt_mac_applicationName()).toNSString()]; - [aboutItem setTitle:qt_mac_applicationmenu_string(6).arg(qt_mac_applicationName()).toNSString()]; + [servicesItem setTitle:qt_mac_applicationmenu_string(ServicesAppMenuItem).toNSString()]; + [hideItem setTitle:qt_mac_applicationmenu_string(HideAppMenuItem).arg(qt_mac_applicationName()).toNSString()]; + [hideAllOthersItem setTitle:qt_mac_applicationmenu_string(HideOthersAppMenuItem).toNSString()]; + [showAllItem setTitle:qt_mac_applicationmenu_string(ShowAllAppMenuItem).toNSString()]; + [preferencesItem setTitle:qt_mac_applicationmenu_string(PreferencesAppMenuItem).toNSString()]; + [quitItem setTitle:qt_mac_applicationmenu_string(QuitAppMenuItem).arg(qt_mac_applicationName()).toNSString()]; + [aboutItem setTitle:qt_mac_applicationmenu_string(AboutAppMenuItem).arg(qt_mac_applicationName()).toNSString()]; #endif } diff --git a/src/plugins/platforms/cocoa/qcocoascreen.h b/src/plugins/platforms/cocoa/qcocoascreen.h index b44f8873e4..3d59c3de79 100644 --- a/src/plugins/platforms/cocoa/qcocoascreen.h +++ b/src/plugins/platforms/cocoa/qcocoascreen.h @@ -98,6 +98,10 @@ public: QList<QPlatformScreen *> m_siblings; }; +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug debug, const QCocoaScreen *screen); +#endif + QT_END_NAMESPACE #endif diff --git a/src/plugins/platforms/cocoa/qcocoascreen.mm b/src/plugins/platforms/cocoa/qcocoascreen.mm index 2c0d04dc3e..ed1b19cd53 100644 --- a/src/plugins/platforms/cocoa/qcocoascreen.mm +++ b/src/plugins/platforms/cocoa/qcocoascreen.mm @@ -288,4 +288,22 @@ QRectF QCocoaScreen::mapFromNative(CGRect rect, QCocoaScreen *screen) return qt_mac_flip(QRectF::fromCGRect(rect), screen->geometry()); } +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug debug, const QCocoaScreen *screen) +{ + QDebugStateSaver saver(debug); + debug.nospace(); + debug << "QCocoaScreen(" << (const void *)screen; + if (screen) { + debug << ", index=" << screen->m_screenIndex; + debug << ", native=" << screen->nativeScreen(); + debug << ", geometry=" << screen->geometry(); + debug << ", dpr=" << screen->devicePixelRatio(); + debug << ", name=" << screen->name(); + } + debug << ')'; + return debug; +} +#endif // !QT_NO_DEBUG_STREAM + QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 8ac3ec228f..c3160e32c2 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -79,6 +79,8 @@ static void qt_closePopups() } } +Q_LOGGING_CATEGORY(lcCocoaNotifications, "qt.qpa.cocoa.notifications"); + static void qRegisterNotificationCallbacks() { static const QLatin1String notificationHandlerPrefix(Q_NOTIFICATION_PREFIX); @@ -110,11 +112,24 @@ static void qRegisterNotificationCallbacks() if (QNSView *qnsView = qnsview_cast(notification.object)) cocoaWindows += qnsView.platformWindow; } else { - qCWarning(lcQpaCocoaWindow) << "Unhandled notifcation" + qCWarning(lcCocoaNotifications) << "Unhandled notifcation" << notification.name << "for" << notification.object; return; } + if (lcCocoaNotifications().isDebugEnabled()) { + if (cocoaWindows.isEmpty()) { + qCDebug(lcCocoaNotifications) << "Could not find forwarding target for" << + qPrintable(notificationName) << "from" << notification.object; + } else { + QVector<QCocoaWindow *> debugWindows; + for (QCocoaWindow *cocoaWindow : cocoaWindows) + debugWindows += cocoaWindow; + qCDebug(lcCocoaNotifications) << "Forwarding" << qPrintable(notificationName) << + "to" << debugWindows; + } + } + // FIXME: Could be a foreign window, look up by iterating top level QWindows for (QCocoaWindow *cocoaWindow : cocoaWindows) { @@ -1427,6 +1442,21 @@ QCocoaNSWindow *QCocoaWindow::createNSWindow(bool shouldBePanel) applyContentBorderThickness(nsWindow); + // Prevent CoreGraphics RGB32 -> RGB64 backing store conversions on deep color + // displays by forcing 8-bit components, unless a deep color format has been + // requested. This conversion uses significant CPU time. + QSurface::SurfaceType surfaceType = QPlatformWindow::window()->surfaceType(); + bool usesCoreGraphics = surfaceType == QSurface::RasterSurface || surfaceType == QSurface::RasterGLSurface; + QSurfaceFormat surfaceFormat = QPlatformWindow::window()->format(); + bool usesDeepColor = surfaceFormat.redBufferSize() > 8 || + surfaceFormat.greenBufferSize() > 8 || + surfaceFormat.blueBufferSize() > 8; + bool usesLayer = view().layer; + if (usesCoreGraphics && !usesDeepColor && !usesLayer) { + [nsWindow setDynamicDepthLimit:NO]; + [nsWindow setDepthLimit:NSWindowDepthTwentyfourBitRGB]; + } + return nsWindow; } diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index a0ffc11967..90a6f936e2 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -1878,6 +1878,7 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin } else { NSImage *nsimage = qt_mac_create_nsimage(pixmapCursor); + nsimage.size = NSSizeFromCGSize((pixmapCursor.size() / pixmapCursor.devicePixelRatioF()).toCGSize()); nativeCursor = [[NSCursor alloc] initWithImage:nsimage hotSpot:NSZeroPoint]; [nsimage release]; } diff --git a/src/plugins/platforms/cocoa/qnswindow.mm b/src/plugins/platforms/cocoa/qnswindow.mm index 799704a407..e846fa043c 100644 --- a/src/plugins/platforms/cocoa/qnswindow.mm +++ b/src/plugins/platforms/cocoa/qnswindow.mm @@ -46,6 +46,8 @@ #include <qpa/qwindowsysteminterface.h> #include <qoperatingsystemversion.h> +Q_LOGGING_CATEGORY(lcCocoaEvents, "qt.qpa.cocoa.events"); + static bool isMouseEvent(NSEvent *ev) { switch ([ev type]) { @@ -116,6 +118,22 @@ static bool isMouseEvent(NSEvent *ev) return qnsview_cast(self.contentView).platformWindow; } +- (NSString *)description +{ + NSMutableString *description = [NSMutableString stringWithString:qt_objcDynamicSuper()]; + +#ifndef QT_NO_DEBUG_STREAM + QString contentViewDescription; + QDebug debug(&contentViewDescription); + debug.nospace() << "; contentView=" << qnsview_cast(self.contentView) << ">"; + + NSRange lastCharacter = [description rangeOfComposedCharacterSequenceAtIndex:description.length - 1]; + [description replaceCharactersInRange:lastCharacter withString:contentViewDescription.toNSString()]; +#endif + + return description; +} + - (BOOL)canBecomeKeyWindow { QCocoaWindow *pw = self.platformWindow; @@ -177,6 +195,8 @@ static bool isMouseEvent(NSEvent *ev) - (void)sendEvent:(NSEvent*)theEvent { + qCDebug(lcCocoaEvents) << "Sending" << theEvent << "to" << self; + // We might get events for a NSWindow after the corresponding platform // window has been deleted, as the NSWindow can outlive the QCocoaWindow // e.g. if being retained by other parts of AppKit, or in an auto-release @@ -185,6 +205,10 @@ static bool isMouseEvent(NSEvent *ev) if (!self.platformWindow) return; + // Prevent deallocation of this NSWindow during event delivery, as we + // have logic further below that depends on the window being alive. + [[self retain] autorelease]; + const char *eventType = object_getClassName(theEvent); if (QWindowSystemInterface::handleNativeEvent(self.platformWindow->window(), QByteArray::fromRawData(eventType, qstrlen(eventType)), theEvent, nullptr)) { @@ -221,6 +245,7 @@ static bool isMouseEvent(NSEvent *ev) #pragma clang diagnostic ignored "-Wobjc-missing-super-calls" - (void)dealloc { + qCDebug(lcQpaCocoaWindow) << "dealloc" << self; qt_objcDynamicSuper(); } #pragma clang diagnostic pop diff --git a/src/plugins/platforms/offscreen/qoffscreenintegration.cpp b/src/plugins/platforms/offscreen/qoffscreenintegration.cpp index 3eb8675d77..75bb786b28 100644 --- a/src/plugins/platforms/offscreen/qoffscreenintegration.cpp +++ b/src/plugins/platforms/offscreen/qoffscreenintegration.cpp @@ -61,6 +61,7 @@ #include <QtGui/private/qguiapplication_p.h> #include <qpa/qplatforminputcontextfactory_p.h> #include <qpa/qplatforminputcontext.h> +#include <qpa/qplatformtheme.h> #include <qpa/qplatformservices.h> @@ -167,6 +168,37 @@ QAbstractEventDispatcher *QOffscreenIntegration::createEventDispatcher() const #endif } +static QString themeName() { return QStringLiteral("offscreen"); } + +QStringList QOffscreenIntegration::themeNames() const +{ + return QStringList(themeName()); +} + +// Restrict the styles to "fusion" to prevent native styles requiring native +// window handles (eg Windows Vista style) from being used. +class OffscreenTheme : public QPlatformTheme +{ +public: + OffscreenTheme() {} + + QVariant themeHint(ThemeHint h) const override + { + switch (h) { + case StyleNames: + return QVariant(QStringList(QStringLiteral("fusion"))); + default: + break; + } + return QPlatformTheme::themeHint(h); + } +}; + +QPlatformTheme *QOffscreenIntegration::createPlatformTheme(const QString &name) const +{ + return name == themeName() ? new OffscreenTheme() : nullptr; +} + QPlatformFontDatabase *QOffscreenIntegration::fontDatabase() const { return m_fontDatabase.data(); diff --git a/src/plugins/platforms/offscreen/qoffscreenintegration.h b/src/plugins/platforms/offscreen/qoffscreenintegration.h index 4c7df207eb..c84c1f7c50 100644 --- a/src/plugins/platforms/offscreen/qoffscreenintegration.h +++ b/src/plugins/platforms/offscreen/qoffscreenintegration.h @@ -69,6 +69,9 @@ public: QPlatformFontDatabase *fontDatabase() const override; QAbstractEventDispatcher *createEventDispatcher() const override; + QStringList themeNames() const; + QPlatformTheme *createPlatformTheme(const QString &name) const; + static QOffscreenIntegration *createOffscreenIntegration(); private: diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp index cf83525c6c..1efb01d52e 100644 --- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp +++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp @@ -992,7 +992,9 @@ void QWindowsNativeFileDialogBase::setMode(QFileDialogOptions::FileMode mode, break; case QFileDialogOptions::Directory: case QFileDialogOptions::DirectoryOnly: - flags |= FOS_PICKFOLDERS | FOS_FILEMUSTEXIST; + // QTBUG-63645: Restrict to file system items, as Qt cannot deal with + // places like 'Network', etc. + flags |= FOS_PICKFOLDERS | FOS_FILEMUSTEXIST | FOS_FORCEFILESYSTEM; break; case QFileDialogOptions::ExistingFiles: flags |= FOS_FILEMUSTEXIST | FOS_ALLOWMULTISELECT; @@ -1201,6 +1203,8 @@ void QWindowsNativeFileDialogBase::onSelectionChange() { const QList<QUrl> current = selectedFiles(); m_data.setSelectedFiles(current); + qDebug() << __FUNCTION__ << current << current.size(); + if (current.size() == 1) emit currentChanged(current.front()); } @@ -1397,7 +1401,7 @@ QList<QUrl> QWindowsNativeOpenFileDialog::dialogResult() const for (IShellItem *item : QWindowsShellItem::itemsFromItemArray(items)) { QWindowsShellItem qItem(item); const QString path = qItem.path(); - if (path.isEmpty()) { + if (path.isEmpty() && !qItem.isDir()) { const QString temporaryCopy = createTemporaryItemCopy(qItem); if (temporaryCopy.isEmpty()) qWarning() << "Unable to create a local copy of" << qItem; diff --git a/src/plugins/platforms/windows/qwindowssystemtrayicon.cpp b/src/plugins/platforms/windows/qwindowssystemtrayicon.cpp index 3ee591de8c..901d132ea5 100644 --- a/src/plugins/platforms/windows/qwindowssystemtrayicon.cpp +++ b/src/plugins/platforms/windows/qwindowssystemtrayicon.cpp @@ -354,7 +354,7 @@ HICON QWindowsSystemTrayIcon::createIcon(const QIcon &icon) m_hIcon = nullptr; if (icon.isNull()) return oldIcon; - const QSize requestedSize(GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON)); + const QSize requestedSize = QSize(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON)); const QSize size = icon.actualSize(requestedSize); const QPixmap pm = icon.pixmap(size); if (!pm.isNull()) diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 24eab2c662..33815eeb54 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -74,6 +74,7 @@ #include <qpa/qwindowsysteminterface.h> #include <QtCore/QDebug> +#include <QtCore/QLibraryInfo> #include <dwmapi.h> @@ -1579,7 +1580,7 @@ void QWindowsWindow::setGeometry(const QRect &rectIn) setFlag(WithinSetGeometry); setGeometry_sys(rect); clearFlag(WithinSetGeometry); - if (m_data.geometry != rect) { + if (m_data.geometry != rect && (isVisible() || QLibraryInfo::isDebugBuild())) { qWarning("%s: Unable to set geometry %dx%d+%d+%d on %s/'%s'." " Resulting geometry: %dx%d+%d+%d " "(frame: %d, %d, %d, %d, custom margin: %d, %d, %d, %d" diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index d97c532b67..e60b5213ff 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -249,7 +249,7 @@ void QXcbConnection::xi2SetupDevice(void *info, bool removeExisting) isTablet = true; tabletData.pointerType = QTabletEvent::Eraser; dbgType = QLatin1String("eraser"); - } else if (name.contains("cursor")) { + } else if (name.contains("cursor") && !(name.contains("cursor controls") && name.contains("trackball"))) { isTablet = true; tabletData.pointerType = QTabletEvent::Cursor; dbgType = QLatin1String("cursor"); |