Cocoa: Fix crash when disconnecting an AirDisplay monitor.

There are some cases where unplugging a monitor temporarily leaves
a QCocoaScreen object with an invalid m_screenIndex. Debugging shows
that the OS does not report the screen update before Qt attempts a
repaint. This calls devicePixelRatio(), which calls osScreen(), and
the index for the screen is out of bounds.

By temporarily exiting updateGeometry() when the screen is unavailable,
we avoid the crash. The OS quickly reports the monitor state change
and everything returns to normal, unnoticed to application.

Task-number: QTBUG-37606
Change-Id: Iacb2ff22bd3df72a5d87b2289242fb393625af57
Reviewed-by: Gabriel de Dietrich <gabriel.dedietrich@digia.com>
Reviewed-by: Morten Johan Sørvig <morten.sorvig@digia.com>
This commit is contained in:
Dyami Caliri 2014-03-18 09:03:36 -07:00 committed by The Qt Project
parent bdf55f62a2
commit 2d8b40439d

View File

@ -81,12 +81,16 @@ QCocoaScreen::~QCocoaScreen()
NSScreen *QCocoaScreen::osScreen() const
{
return [[NSScreen screens] objectAtIndex:m_screenIndex];
NSArray *screens = [NSScreen screens];
return ((NSUInteger)m_screenIndex < [screens count]) ? [screens objectAtIndex:m_screenIndex] : nil;
}
void QCocoaScreen::updateGeometry()
{
NSScreen *nsScreen = osScreen();
if (!nsScreen)
return;
NSRect frameRect = [nsScreen frame];
if (m_screenIndex == 0) {
@ -143,7 +147,8 @@ qreal QCocoaScreen::devicePixelRatio() const
{
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7) {
return qreal([osScreen() backingScaleFactor]);
NSScreen * screen = osScreen();
return qreal(screen ? [screen backingScaleFactor] : 1.0);
} else
#endif
{