From bfcad18526dc064ac7dd1a08781c60d1d1673a0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 2 Nov 2017 20:52:47 +0100 Subject: macOS: Replace deprecated CGDisplayIOServicePort function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There's no replacement function from Apple's side, so we have to iterate the available displays and pick the right one based on the vendor, product and serial number. Change-Id: I437bee06bc6826c3214a701cd2c65f6109eeb3e7 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoahelpers.h | 13 ++++++++++ src/plugins/platforms/cocoa/qcocoahelpers.mm | 15 +++++++++++ src/plugins/platforms/cocoa/qcocoascreen.mm | 39 +++++++++++++++++++++++----- 3 files changed, 61 insertions(+), 6 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.h b/src/plugins/platforms/cocoa/qcocoahelpers.h index 7810733255..bc0cd547cf 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.h +++ b/src/plugins/platforms/cocoa/qcocoahelpers.h @@ -193,6 +193,19 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSPanelContentsWrapper); // ------------------------------------------------------------------------- +// QAppleRefCounted expects the retain function to return the object +io_object_t q_IOObjectRetain(io_object_t obj); +// QAppleRefCounted expects the release function to return void +void q_IOObjectRelease(io_object_t obj); + +template +class QIOType : public QAppleRefCounted +{ + using QAppleRefCounted::QAppleRefCounted; +}; + +// ------------------------------------------------------------------------- + // Depending on the ABI of the platform, we may need to use objc_msgSendSuper_stret: // - http://www.sealiesoftware.com/blog/archive/2008/10/30/objc_explain_objc_msgSend_stret.html // - https://lists.apple.com/archives/cocoa-dev/2008/Feb/msg02338.html diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm index 9f9618177d..67d42a2544 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.mm +++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm @@ -408,4 +408,19 @@ QT_END_NAMESPACE [super layout]; } +// ------------------------------------------------------------------------- + +io_object_t q_IOObjectRetain(io_object_t obj) +{ + kern_return_t ret = IOObjectRetain(obj); + Q_ASSERT(!ret); + return obj; +} + +void q_IOObjectRelease(io_object_t obj) +{ + kern_return_t ret = IOObjectRelease(obj); + Q_ASSERT(!ret); +} + @end diff --git a/src/plugins/platforms/cocoa/qcocoascreen.mm b/src/plugins/platforms/cocoa/qcocoascreen.mm index 13e5220b6a..4bd26458a4 100644 --- a/src/plugins/platforms/cocoa/qcocoascreen.mm +++ b/src/plugins/platforms/cocoa/qcocoascreen.mm @@ -103,6 +103,38 @@ QRectF QCocoaScreen::flipCoordinate(const QRectF &rect) const return QRectF(flipCoordinate(rect.topLeft() + QPoint(0, rect.height())), rect.size()); } +static QString displayName(CGDirectDisplayID displayID) +{ + QIOType iterator; + if (IOServiceGetMatchingServices(kIOMasterPortDefault, + IOServiceMatching("IODisplayConnect"), &iterator)) + return QString(); + + QIOType display; + while ((display = IOIteratorNext(iterator)) != 0) + { + NSDictionary *info = [(__bridge NSDictionary*)IODisplayCreateInfoDictionary( + display, kIODisplayOnlyPreferredName) autorelease]; + + if ([[info objectForKey:@kDisplayVendorID] longValue] != CGDisplayVendorNumber(displayID)) + continue; + + if ([[info objectForKey:@kDisplayProductID] longValue] != CGDisplayModelNumber(displayID)) + continue; + + if ([[info objectForKey:@kDisplaySerialNumber] longValue] != CGDisplaySerialNumber(displayID)) + continue; + + NSDictionary *localizedNames = [info objectForKey:@kDisplayProductName]; + if (![localizedNames count]) + break; // Correct screen, but no name in dictionary + + return QString::fromNSString([localizedNames objectForKey:[[localizedNames allKeys] objectAtIndex:0]]); + } + + return QString(); +} + void QCocoaScreen::updateGeometry() { NSScreen *nsScreen = nativeScreen(); @@ -139,12 +171,7 @@ void QCocoaScreen::updateGeometry() if (refresh > 0) m_refreshRate = refresh; - // Get m_name (brand/model of the monitor) - NSDictionary *deviceInfo = (NSDictionary *)IODisplayCreateInfoDictionary(CGDisplayIOServicePort(dpy), kIODisplayOnlyPreferredName); - NSDictionary *localizedNames = [deviceInfo objectForKey:[NSString stringWithUTF8String:kDisplayProductName]]; - if ([localizedNames count] > 0) - m_name = QString::fromUtf8([[localizedNames objectForKey:[[localizedNames allKeys] objectAtIndex:0]] UTF8String]); - [deviceInfo release]; + m_name = displayName(dpy); QWindowSystemInterface::handleScreenGeometryChange(screen(), geometry(), availableGeometry()); QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(screen(), m_logicalDpi.first, m_logicalDpi.second); -- cgit v1.2.3