Dans Mac OS X, chaque affichage obtient un numéro Un identifiant d'affichage peut persister à travers
processus et redémarrage du système, et
reste généralement constant aussi longtemps que
Certains paramètres d'affichage ne font pas
changer. p>
BlockQuote> On Newer Mid-2010 MacBook Pro, Apple a commencé à utiliser l'interrupteur automatique Intel / Nvidia Graphics. Les ordinateurs portables ont deux GPU, un Intel à faible consommation et une Nvidia à haute puissance. Les ordinateurs portables Dual-GPU précédents (modèles 2009) n'ont pas eu la commutation GPU Auto-GPU et l'utilisateur de modifier, déconnectez-vous, puis de vous connecter à nouveau pour effectuer un commutateur GPU. Même les systèmes plus anciens n'avaient qu'un GPU. P> Il y a un problème avec les modèles de la mi-2010 où CGDirectDisplayID ne reste pas la même lorsque un écran passe d'un GPU à l'autre. Par exemple: p> J'ai remarqué que l'identifiant d'affichage n'envoie que 2, mais je n'ai pas assez de test Mac disponible pour déterminer si cela est commun à tout le nouveau MacBook Pro est, ou juste le mien. Type d'un kludge si "Vérifiez simplement les identifiants d'affichage qui sont +/- 2 les uns des autres" fonctionne, de toute façon. P> CGDirectDisplayID (code> CGDirectDisplayID code> attribué à celui-ci. Vous pouvez utiliser
cggetactiveSisplayList ( code>) ou
[écrans nscreen] code> pour y accéder, entre autres. Par Documents d'Apple :
cgdisplayregisterReconfigurationCallback () code>, qui notifie avant-et-après lorsque les affichages vont changer, aucune logique correspondante. Mettre quelque chose comme ça à l'intérieur d'une méthode enregistrée ne fonctionne pas: P>
// oldInfoDict (Display ID: 30002)
oldInfoDict: {
DisplayProductID = 40144;
DisplayVendorID = 1552;
IODisplayLocation = "IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/IGPU@2/AppleIntelFramebuffer/display0/AppleBacklightDisplay";
}
// newInfoDict (Display ID: 30004)
newInfoDict: {
DisplayProductID = 40144;
DisplayVendorID = 1552;
IODisplayLocation = "IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/P0P2@1/IOPCI2PCIBridge/GFX0@0/NVDA,Display-A@0/NVDA/display0/AppleBacklightDisplay";
}
4 Réponses :
Bien que je ne suis pas pro, je pense que la réponse est d'autoriser Apple L'utilisateur ne doit pas ajouter ou supprimer des cartes graphiques pendant le fonctionnement. Je vais donc jouer avec la liste de fabrication au démarrage, et chaque fois que vous obtenez le drapeau "Supprimer" définir l'opération "Ajouter" suivante pour remplacer cet ID dans la liste. . p>
J'essaierais d'imprimer des informations que vous récupérez chaque fois que C'est mon meilleur pari, espérons que cela aide! P> cgdirectdisplayID code> s. P>
cgdisplayregisterReconfigurationCallback code> appelle votre fonction. Voyez si vous en obtenez un avec un appareil avec un drapeau "Supprimer", puis un appel ultérieur d'un autre avec un drapeau "Ajouter". Vérification de ces identifiants contre
cggetactiveSisplayList code> aiderait également à comprendre ce qui se passe. P>
Merci Stephen. Malheureusement, la notification n'a rien de dire "DisplayID ABC est devenu affichée XYZ". Ce que j'ai découvert depuis l'affichage de cette question est l'identifiant d'affichage peut changer de manière dynamique à l'exécution à tout moment. Par exemple, si vous lancez Adobe Photoshop CS4, le commutateur MacBook Pro Mid-2010 de Intel intégré Graphics à Nvidia discret graphique. Cela a du sens puisque Photoshop CS4 + est intensive GPU. Cependant, l'affichage pour votre moniteur change lors de commutateurs GPU. Une fois que vous existez Photoshop, il retombe au GPU Intel, et le displayID change à nouveau. Amusant! :)
True, mais vous devriez toujours obtenir un rappel pour l'ID Supprimer et un pour l'identifiant Ajouter, non?
@DaveGallagher Avez-vous essayé d'utiliser cfuuidref? Cfuuidref de mon expérience anecdotique a toujours été cohérent, même lorsque CGDirectDisplayID change, même à travers les redémarrages.
Je n'ai trouvé aucun moyen de mieux que vous lisez comme "essayé". Mais j'ai trouvé une solution pour la question de l'ambiguïté de comparer uniquement l'ID de fournisseur et l'ID de produit.
oldinfodict code> et
newinfodict code> dans votre code contient une entrée supplémentaire pour la clé
kiodispleedidkkey code> (défini dans iographicstypes .h ) qui contient le EDID de chaque écran connecté. Mes observations montrent que ces données comme un reste persistante entre les commutateurs GPU. Par exemple: P>
CGDirectDisplayID displayId = [[[screen deviceDescription] valueForKey:@"NSScreenNumber"] unsignedIntValue];
io_service_t displayPort = CGDisplayIOServicePort(displayId);
if (displayPort == MACH_PORT_NULL)
return nil; // No physical device to get a name from.
CFDictionaryRef infoDict = IODisplayCreateInfoDictionary(displayPort, kIODisplayOnlyPreferredName);
NSData *displayEdid = (NSData *)CFDictionaryGetValue(infoDict, CFSTR(kIODisplayEDIDKey));
NSLog(@"EDID: %@", displayEdid);
CFRelease(infoDict);
Savez-vous si le blob de données EDID est unique pour chaque affichage i>? C'est-à-dire que deux écrans Thunderbolt aura-t-il différentes blobs EDID? Notez que le "numéro de série" est toujours zéro, de sorte qu'un autre aspect de l'EDID doit être différent. Fondamentalement, je cherche un moyen fiable d'identifier le même écran physique dans toutes les conditions.
Voulez-vous dire deux modèles d'affichage identiques connectés sur Thunderbolt? Si ce n'est pas le même modèle ni même différents fournisseurs, je suis à peu près sûr que l'EDID sera différent. Si c'est la même marque et le même modèle, et que la série n'est pas peuplée, il peut être difficile de les distinguer. La série étant zéro pourrait être un problème spécifique du fournisseur, avez-vous essayé différents écrans?
Je n'ai pas essayé d'autres fournisseurs, mais les écrans d'Apple ont définitivement le numéro de série défini à zéro.
Utilisez cfuuidref qui peut être obtenu en utilisant: p>
C'est ce que j'utilise pour identifier de manière unique des écrans, même lorsque leurs modifications de CGDirectDisplayID, par exemple ont été branchées dans un autre port. Ces fonctions ne sont pas correctement documentées par Apple malheureusement, mais mes tests sur plusieurs Mac avec plusieurs écrans montrent que le CFUUIDREF obtenu est unique et cohérent après un redémarrage-, quel que soit le cas de la cgdirectDisplayID de quelque raison que ce soit. P>
Pour vérifier si un affichage est neuf / unique, prenez son CGDirectDisplayID et la convertissez-le en CFUUIDREF, puis comparez l'UUID, il s'agit d'une relation multiple à une, de nombreux CGDirectDisplayIDS planeront dans un seul CFUUIDRF. P >
Ces appels d'API sont disponibles dans ApplicationsVices en 10.7 - 10.12 et ColorSync depuis 10.13. P> cgdisplaycreaueuidfromdisplayID (CGDirectDisplayID displayID) code>
et vous pouvez récupérer l'affichage à l'aide de: p>
cgdisplayGetDisplayIDFromuuid (UUID CFUUIDREF) code> p>
J'ai utilisé: Toutefois, lors d'un événement d'élimination de l'affichage dans le rappel, même pendant le intéressant, on peut toujours obtenir le Array de Nscreens et recherchez une correspondance du CGDirectDisplayID: P> en xcode le kcgdisplaybeginconfigurationflag code>, l'appel à
cgdisplaycreauuidfromdisplayID code> échoue avec une erreur "displayid invalide", donc je ne vois donc aucun moyen de passer d'un CGDirectDisplayID ambigu à une UUID stable lorsqu'un écran est enlevé. P>
[[[[[[Écran DeviceDescription] ObjectForkey: @ "Nscreennumber"] UnsignedLongValue] P>
nscreen code> a une propriété appelée
_uuidstring code> qui contient le même uuid mais je ne vois aucun moyen d'obtenir cet uuid hors du Nscreen. p> p>
Lorsqu'un changement de GPU se produit, les drapeaux envoyés au rappel incluent un non-documenté:
#define kcgdisplaymysterygpugedflag (1 << 13) // drapeau de rappel post-reconfiguration non documenté pour systèmes I5 / I7 CODE>