В Mac OS X каждый дисплей получает уникальный CGDirectDisplayID
номер, присвоенный ему. Вы можете использовать CGGetActiveDisplayList(
) или [NSScreen screens]
для доступа к ним, среди прочих. Per Документы Apple:
Идентификатор дисплея может сохраняться процессы и перезагрузка системы; обычно остается постоянной, пока определенные параметры отображения не изменение.
В новом MacBook Pro середины 2010 года Apple начала использовать графику Intel/nVidia с автоматическим переключением. Ноутбуки имеют два GPU, маломощную Intel и мощную nVidia. Предыдущие двухпроцессорные ноутбуки (модели 2009 года) не имели автоматического переключения на GPU и требовали от пользователя изменения настроек, выхода из системы и повторного входа в систему, чтобы сделать коммутатор GPU. Даже более старые системы имели только один графический процессор.
Проблема с моделями середины 2010 года, когда CGDirectDisplayID не остается прежним, когда дисплей переключается с одного GPU на другой. Например:
- Питание от ноутбука.
- Встроенный ЖК-дисплей Экран управляется чипсетом Intel. Идентификатор дисплея: 30002
- Внешний Дисплей подключен.
- Встроенный ЖК-экран переключается на nVidia Набор микросхем. Он отображает идентификационные изменения: 30004
- Внешний дисплей чипсетом nVidia.
- ... в этот момент, чипсет Intel неактивен...
- Пользователь отключает Внешний дисплей.
- Встроенный ЖК-экран переключается на Чипсет Intel. Он отображает идентификатор возвращается к оригиналу: 30002
Мой вопрос: как я могу сопоставить старый идентификатор дисплея с новым идентификатором отображения, когда они изменяются из-за изменения графического процессора?
Мысль о:
Я заметил, что идентификатор дисплея изменяется только на 2, но у меня недостаточно тестового Mac, чтобы определить, является ли это общим для всех новых MacBook Pro, или просто для меня. Во всяком случае, работает "kludge", если "просто проверьте идентификатор дисплея, которые +/- 2 друг от друга".
Пробовал:
CGDisplayRegisterReconfigurationCallback()
, который уведомляет до и после, когда дисплеи будут меняться, не имеет соответствующей логики. Вложение чего-то подобного внутри метода, зарегистрированного в нем, не работает:
// Run before display settings change:
CGDirectDisplayID directDisplayID = ...;
io_service_t servicePort = CGDisplayIOServicePort(directDisplayID);
CFDictionaryRef oldInfoDict = IODisplayCreateInfoDictionary(servicePort, kIODisplayMatchingInfo);
// ...display settings change...
// Run after display settings change:
CGDirectDisplayID directDisplayID = ...;
io_service_t servicePort = CGDisplayIOServicePort(directDisplayID);
CFDictionaryRef newInfoDict = IODisplayCreateInfoDictionary(servicePort, kIODisplayMatchingInfo);
BOOL match = IODisplayMatchDictionaries(oldInfoDict, newInfoDict, 0);
if (match)
NSLog(@"Displays are a match");
else
NSLog(@"Displays are not a match");
Что происходит выше:
- Я делаю кеширование oldInfoDict до изменения настроек отображения.
- Ожидание изменения параметров отображения
- Затем сравнивая oldInfoDict с newInfoDict с помощью
IODisplayMatchDictionaries()
-
IODisplayMatchDictionaries()
возвращает BOOL, либо они одинаковы, либо они не отличаются.
К сожалению, IODisplayMatchDictionaries()
не возвращает YES, если один и тот же дисплей изменил графический процессор. Здесь пример словаря, который он сравнивает (посмотрите на ключ IODisplayLocation
):
// oldInfoDict (Display ID: 30002)
oldInfoDict: {
DisplayProductID = 40144;
DisplayVendorID = 1552;
IODisplayLocation = "IOService:/AppleACPIPlatformExpert/[email protected]/AppleACPIPCI/[email protected]/AppleIntelFramebuffer/display0/AppleBacklightDisplay";
}
// newInfoDict (Display ID: 30004)
newInfoDict: {
DisplayProductID = 40144;
DisplayVendorID = 1552;
IODisplayLocation = "IOService:/AppleACPIPlatformExpert/[email protected]/AppleACPIPCI/[email protected]/IOPCI2PCIBridge/[email protected]/NVDA,[email protected]/NVDA/display0/AppleBacklightDisplay";
}
Как вы можете видеть, клавиша IODisplayLocation
изменяется при переключении GPU, поэтому IODisplayMatchDictionaries()
не работает.
Теоретически я могу сравнить только ключи DisplayProductID
и DisplayVendorID
, но я пишу программное обеспечение конечного пользователя, и меня беспокоит ситуация, когда пользователи имеют два или более одинаковых монитора, подключенных к сети (это означает, оба имеют одинаковый DisplayProductID/DisplayVendorID). Другими словами, это менее совершенное решение, открытое для потенциальных сбоев.
Любая помощь очень ценится!:)